• Ошибка Failed prop type: Invalid prop `children` supplied to `ForwardRef(Box)`, expected a ReactNode. Что я делаю не так?

    Aetae
    @Aetae
    Тлен
    React так не умеет. Сам механизм react делает такое невозможным.
    Все компоненты синхронны(кроме lazy, но это совсем другое).
    Ты должен свою асинхронную функцию вызвать в useEffect, а пока она грузится показывать какой-нить лоадер.
    Ответ написан
    1 комментарий
  • Как сделать что бы border не растягивался на всю страницу а только шёл до последней буквы?

    Aetae
    @Aetae
    Тлен
    display: inline-block;?
    Ответ написан
    Комментировать
  • Как сделать чтобы padding-right добавлялся только при overflow?

    Aetae
    @Aetae
    Тлен
    Для ширины скролла есть небольшой магический хак:
    Если 100% - ширина экрана(и ваш контейнер растянут по всей ширине), то: calc(100vw - 100%) - ширина сколлбара. Используя это - можно что-то намагичить.:)

    ...upd: чтоб получить своё точное значение, независимо от ширины скроллбара, можно сделать так: calc(min(100vw - 100%, 1px) * 10), где результат min будет 1px или 0px в зависимости от наличия скроллбара, а 10 - любой нужный множитель.:)

    ...upd2:
    Если ширина контейнера не равна ширине экрана, но как-то от неё всё-же зависит - всё то же самое, только чутка математики добавить.
    Если ширина контейнера никак не зависит, то пока похоже действительно никак. (хотя может я и упускаю что-то)
    Однако в будушем css можно будет, используя пару трюков:
    1. Вот так уже можно в самом свежем хроме используя animation scroll(): https://www.bram.us/2023/09/16/solved-by-css-scrol...
    2. Используя qw (ширину контейнера) можно будет когда таки работа с контейнерам доедет до браузеров.
    Ответ написан
    Комментировать
  • Почему JS код выполняется повторно?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Проблема не в этом коде, очевидно:
    Скорее всего ты просто подключаешь этот код два раза. Проищи внимательнее.
    Ответ написан
    Комментировать
  • Ошибка Error: Hydration failed because the initial UI does not match what was rendered on the server. Как исправить?

    Aetae
    @Aetae
    Тлен
    Очевидная проблема в том, что ты рендеришь страницу по разному в зависимости от свойств экрана юзера, однако сервер не знает ничего об юзерском экране, потому результат SSR и результат на клиенте - разный, что и вызывает ошибки гидрации.

    Красивого решения тут нет, только разные костыли, например:
    1. Первый раз рендерить компонент всегда одинаково, а потом уже обновлять по useEffect в зависимости от экрана. Простое решение которое сразу заработает, однако может привести к кратковременном миганию на клиенте при загрузке.
    1а. Вычислять по userAgent что у клиента мобила\планшет и первым рисовать наиболее вероятный вариант, а потом уже по useEffect использовать точный, если не угадали. Тоже самое но есть шанс что угадаем.
    2. Рисовать все варианты на странице, а скрывать тупо классами css не используя этой либы. Тоже сразу заработает, но на странице куча мусора.
    3. ?
    Ответ написан
    Комментировать
  • Почему .value в nuxt3 выдает не тот результат в консоли?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Во первых: всё зависит от сигнатуры этого вашего useApiFetch, очень многое в vue 3 можно сломать неудачной деструктуризацией. Но допустим сам хук нормальный.
    В таком случае isPending - это ref, а значит он и должен быть прокси, чтоб собственно работала энтая самая реактивность. Чтоб отобразить в консоли чистый объект - есть хэлпер toRaw(только после этого он уже не будет динамическим).

    Далее: если вы выводите в консоль isPending.value - то в консоль, очевидно, попадает значение на момент вызова console.log. Магическим образом прямо в консоли оно уже не изменится.

    Если ты хочешь понаблюдать за изменениями isPending - можешь сделать так:
    watch(isPending, (value) => console.log('watch isPending', value), { immediate: true });


    В заключение предположу, что всё у вас работает как должно, а проблемы с пониманием реактивности vue и асинхронности как таковой.
    Ответ написан
    Комментировать
  • Каким образом вывести (интерполировать) данные из переменных в title?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Ну например глобальный миксин приблизительно такого вида:
    {
      beforeCreate() {
        this._oldTitle = document.title;
      },  
      unmounted() {
        if (this.PAGE_TITLE)
          document.title = this._oldTitle;
      },
      watch: {
        PAGE_TITLE: {
          handler(val, oldVal) {
            if (val)
              document.title = val;
            else
              document.title = this._oldTitle;
          },
          immediate: true
        },
      }
    }

    И в компоненте управляешь просто свойством this.PAGE_TITLE.
    Или в случае composition api:
    const PAGE_TITLE = ref('<title>'); // computed(() => ...)
    // ...
    return { 
      PAGE_TITLE,
      // ...
    }

    и в случае script setup/render:
    + expose({ PAGE_TITLE })

    Особенность в том, что управление title тут заберёт последний загруженный компонент имеющий PAGE_TITLE, что может привести к багам если на одной странице таких окажется два.

    У меня есть где-то самописка которая делает подобное но с учётом роутера и иерархии, и это уже, увы не так просто.:)

    P.S. Вообще на таком примитивном уровне можно просто использовать document.title напрямую и не париться. Подход с миксином имеет смысл если этот title вы используете ещё где-то в приложении глобально.
    Ответ написан
    3 комментария
  • Проект на VueJS контейнер Docker. Почему не запускается?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Очевидно надо достать кусок кода в index-yQz08yST.js:9:2359 (девятая строка 2359 символ) и посмотреть в чём там проблема.
    Навскидку по тексту ошибки могу предположить, что там используется optional chaining (foo?.bar) или nullish coalescing (foo ?? bar), а версия браузера у вас там старая и не поддерживает такой фичи.

    ...upd: судя по user-agent там хром 70, а минимум для этих фич - хром 80.
    Если моё предположение верно(99%), то у вас два варианта: обновить хром на машине, или добавить в билд babel(скорее всего и так добавлен) и прописать в browserlist Chrome <= 70 (а не last 1, что там скорее всего по умолчанию), чтоб при билде он эти фичи заменил на старые альтернативы.
    Ответ написан
    1 комментарий
  • Как заменить стиль эмодзи на сайте?

    Aetae
    @Aetae
    Тлен
    Apple - копирайчен, можешь попасть, если переоценишь свою "неуловимость".:)
    А так - да, клятые эмодзи - часть шрифта, просто вписываешь нужный шрифт через запятую и всё заработает:

    А шрифты ты уж, будь добр, сам гугли, какие тебе надо.
    Ответ написан
    Комментировать
  • Как написать Vue компонент не для браузера?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Vue завязан на html+javascript. Даже серверный рендер просто возвращает html-строку. Возможно можно написать собственный рендер vdom-терминал или использовать какой-то имеющийся конвертер html-терминал, но это всё сомнительно и мутно. Вам следует поискать другие инструменты.
    Ответ написан
  • Как задать логику преобразования объекта в массив?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Что-то типа такого:
    class Users {
      constructor() {
        this.store = []
      }
      [Symbol.iterator] = () => this.store[Symbol.iterator]() 
    }
    Но взможно вам проще и красивее будет сделать самих User'ов наследником массива:
    class Users extends Array {
      constructor() {
        super();
      }
    }
    И использовать сразу this вместо this.store со всеми методами массива кроме тех которые вы переопределите:).
    Ответ написан
    3 комментария
  • Quasar не видит теги MathML и принимает их за компоненты?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Забей эту ошибку в гугл транслейт раз в англицкий не разумеешь. Ответ прямо в ней написан. ¯\_(ツ)_/¯
    Ответ написан
    1 комментарий
  • Как передать пропсы в компонент через цикл?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    let newsListItem = defineProps({
      newsListItem: Object
    });

    ->
    defineProps({
      newsListItem: Object
    });

    или, если нужно использование свойств не только в шаблоне:
    const props = defineProps({
      newsListItem: Object
    });


    1. Завяленные свойства по умолчанию уже есть в шаблонах.
    2. defineProps - возвращает реактивный объект props целиком, а не какое-то конкретное из свойств.
    Ответ написан
  • Как узнать высотку потомка?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    По хорошему - тебе это не должно быть нужно. В 99% случаев возникновение такой необходимости говорит о том, что где-то в структуре закралась ошибка (либо о неумении верстать).

    В оставшемся 1%: element ref + ResizeObserver (или какая-нить готовая директива, которая сделает то же самое под капотом).
    Ответ написан
    Комментировать
  • Как происходит кеширование, если вызывает функция slow?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    В js функция не является чем-то особенным и неприкасновенным.

    function slow(x) { ... }
    Утириовано: создана функция и положена в переменную slow, аналогично:
    var slow;
    slow = function (x) { ... };


    slow = cachingDecorator(slow);
    Пишем в переменную результат вызова cachingDecorator с аргументом из slow.

    Всё происходит по порядку:
    0. Создаётся функция и кладётся в пременую slow.
    1. Берётся текушая функция из slow.
    2. Кладётся в аргуметы cachingDecorator.
    3. Результат cachingDecorator(slow) кладётся в переменную slow.

    Есть всякие нюансы и оговорки, но в целом не следует переусложнять, со всеми сущностями в js можно работать одинаково.
    Ответ написан
    5 комментариев
  • Как добавить в каждый объект массива новое свойство?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Ответ drawnofmymind не отвечает на заданный вопрос "как добавить", т.к. создаёт полностью новый массив с полностью новыми объектами.

    В некоторых случаях это предпочтительнее(когда необходима иммутабельность), но ответ именно на заданный вопрос куда проще:
    items.forEach(item => item.alert = false)
    Ответ написан
    1 комментарий
  • Как реактифицировать подгруженный html кусок разметки?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    import {compile} from "vue"
    
    compile('<custom-component />') // возвращает render-функцию.
    Ответ написан
    2 комментария
  • Возможно ли изменить поведение contentEditable?

    Aetae
    @Aetae
    Тлен
    Поменять поведение - нельзя.
    Отслеживать изменения и переписывать - можно, но не нужно.
    Ответ написан
    Комментировать
  • Как сделать фильтрацию?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Чтоб сделать фильтрацию просто делаешь так:
    const [selected, setSelected] = useState('all');
    
      let filterdTodos;
      switch(selected) {
        case 'all':
          filterdTodos = todos;
          break;
        case 'checked':
          filterdTodos = todos.filter(t => t.checked);
          break;
        case 'notChecked':
          filterdTodos = todos.filter(t => !t.checked);
          break;
      }

    Или так, с оптимизацией:
    const [selected, setSelected] = useState('all');
    
      const filterdTodos = useMemo(() => {
        switch(selected) {
          case 'all':
            return todos;
          case 'checked':
            return todos.filter(t => t.checked);
          case 'notChecked':
            return todos.filter(t => !t.checked);
        }
      }, [selected, todos])

    <select className="todos__filter" onChange={(event) =>setSelected(event.target.value)}>
    ...
    {filterdTodos.map(...)}
    Ответ написан
  • Как решить проблему исчезновения данных товаров при перезагрузке страницы во Vue.js приложении?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Во-первых: не используй onMounted внутри стора. onMounted - это хук компонента, а не стора. Оно работает только благодаря стечению обстоятельств.
    Во вторых: products должны быть ref. Сейчас они не реактивны(никак не реагируют на изменения). При этом ты присваииваешь массиву value. То что это хоть как-то работало - очередное чудо.
    В-третьих: ты должен учитывать, что какое-то время данные будут грузиться и показывать лоадер пока их нет.

    В общем если загрузка должна начинаться в лбом случае при первой инициализации store'a(обычно загрузку привязывают к маршрутам или компонентам), то выглядеть оно будет как-то так:
    export const useAllMainFiltersStore = defineStore('allMainFilters', () => {
      const products = ref([]);
    
      try {
        async function getStoreData() {
          sidebarResizeStore.updateSidebarVisibility()
          const data = await productsData();
          products.value = data;
        }
        getStoreData()
      } catch (error) {
        console.error('Error:', error);
      }
      
      return {
        products,
      }
    })


    В компоненте:
    const route = useRoute();
    // продукт делаем вычисляемым, чтоб не городить вотчеров
    const product = computed(() => getProductById(route.params.id));
    
    function getProductById(id) {
      console.log('products component: ', mainFiltersStore.products) //при первой загрузке всё ок, при перезагрузке страницы всё ломается и пустой массив в придачу
      return products.find(product => product.id == id);
    }
    
    watch(product, current => {
      // проверяем что продукт есть
      if (current) fetchComments(current.id);
    }, { immediate: true })
    Ответ написан
    3 комментария