Ответы пользователя по тегу Vue.js
  • Почему возвращает undefined?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    1. Проблема в том, что возвращает твой postForm. Сам по себе приведённых код рабочий. Нужен код postForm.
    2. Хотя приведённый код и рабочий - так писать нельзя: ты используешь либо Options Api, либо Composition Api. Не смешивая. Если есть setup - нет methods, если есть methods - нет setup. Да, оно работает. Но это говно. Как Тесла с дизель-генератором в багажнике.
    Ответ написан
  • Почему .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 комментарий
  • Как написать Vue компонент не для браузера?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Vue завязан на html+javascript. Даже серверный рендер просто возвращает html-строку. Возможно можно написать собственный рендер vdom-терминал или использовать какой-то имеющийся конвертер html-терминал, но это всё сомнительно и мутно. Вам следует поискать другие инструменты.
    Ответ написан
  • 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 (или какая-нить готовая директива, которая сделает то же самое под капотом).
    Ответ написан
    Комментировать
  • Как реактифицировать подгруженный html кусок разметки?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    import {compile} from "vue"
    
    compile('<custom-component />') // возвращает render-функцию.
    Ответ написан
    2 комментария
  • Как решить проблему исчезновения данных товаров при перезагрузке страницы во 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 комментария
  • Почему на прод версии выдаёт ошибку?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Ответ очевиден - не использовать недокументированные* свойства типа __vueParentComponent.:)

    Раз ты используешь options api у тебя есть this.$parent для родительского компонента или ты можешь использовать ref для выбора конкретного.

    Однако в любом случае обращение к родителю выглядит как говнокод. Пробрасывай значение в props из родителя и не городи огород.

    * Работа в режиме разработки и в режиме продакшена очень сильно отличается. Даже если ты видишь какие-то свойства в консоли, то, если они не документированы, значит полагаться на то, что ни будут там всегда - ни в коем случае нельзя. Особенно на явно помеченные как внутренние через нижнее подчёркивание.
    Ответ написан
    Комментировать
  • Как добавить готоую форму amoCrm в Vue3?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Я хз что такое AmoCrm, но если надо тупо добавить не-vue скрипы как vue-компонент, то как-то так:
    import { ref, h } from 'vue';
    
    function loadScript(options, root = document.head) {
      return root.appendChild(Object.assign(document.createElement('script'), options));
    }
    
    const Comp = defineComponent(() => {
      const root = ref(null);
    
      onMounted(() => {
        loadScript(
          {
            innerHTML: `
          !(function (a, m, o, c, r, m) {
        (a[o + c] = a[o + c] || {
            setMeta: function (p) {
                this.params = (this.params || []).concat([p]);
            },
        }),
            (a[o + r] =
                a[o + r] ||
                function (f) {
                    a[o + r].f = (a[o + r].f || []).concat([f]);
                }),
            a[o + r]({
                id: "....",
                hash: "....",
                locale: "ru",
            }),
            (a[o + m] =
                a[o + m] ||
                function (f, k) {
                    a[o + m].f = (a[o + m].f || []).concat([[f, k]]);
                });
    })(window, 0, "amo_forms_", "params", "load", "loaded");
          `
          },
          root.value
        );
        loadScript(
          {
            id: 'amoforms_script_...',
            async: 'async',
            charset: 'utf-8',
            src: 'https://forms.amocrm.ru/forms/assets/js/amoforms.js?...'
          },
          root.value
        );
      });
    
      return () => h('div', { ref: root });
    });
    Ответ написан
  • Как и где можно фиксировать и сохранять данные до изменений в multiselect?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    В entity.selectedAccesses лежит последнее значение =\
    Ответ написан
    9 комментариев
  • Как добавить аттрибут к тегу без занчения?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Одиночный тег - это active="".
    Ну и да, по возможности выкинь нафиг jq, это очень плохая практика.
    Ответ написан
    Комментировать
  • Почему не работает addTag в multiselect?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Судя по документации тэг добавляется также и в модель(т.е. в entity.selectedAccesses), а не только в options(что называется у тебя value).

    С учётом слота, можно сделать примерно так:
    Ответ написан
  • Smooth scroll to anchor links in Nuxt3 как сделать?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Точно также как и не в nuxt.
    function manualSmoothScroll(event) {
      // находим хэш ссылу по которой мы кликнули
      const id = event.target.closest('a[href^="#"]')?.hash;
      // если клик куда-то ещё - ничего не делаем
      if (!id) return;
      
      
      // находим цель куда будем скроллить по хэшу
      const target = document.querySelector(id);
      // если не нашли - ничего не делаем
      if (!target) return;
      
      // отменяем стандартный переход
      event.preventDefault();
      // едем руками
      target.scrollIntoView({ behavior: "smooth" });
    }
    
    // при загрузке
    addEventListener('click', manualSmoothScroll, true);
    
    
    // при выгрузке
    removeEventListener('click', manualSmoothScroll, true);
    
    // если действовать надо только в рамках элнметата
    // elementRef.value.addEvent... elementRef.value.removeve... 
    // или this.$refs.element... 
    // или this.$el...
    Ответ написан
    1 комментарий
  • Как во Vue Router указать не обязательную часть url?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    На обычном Vue роутере такие маршруты делаются примерно так:
    {
    		path: '/catalog/mebel', 
    		children: [
    			{
    				path: 'page-:page(\\d+)?', 
    				alias: '',
    				component: Mebel,
    			},
    			{
    				path: ':category', 
    				children: [
    					{
    						path: 'page-:page(\\d+)?', 
    						alias: '',
    						component: MebelCategory
    					},
    					{
    						path: ':article', 
    						component: MebelArticle
    					}
    				]
    			},
    		], 
    	}



    В nuxt это можно добавить\изменить тут.
    Ответ написан
    Комментировать
  • VUE 3 Router не видит GET параметры?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Видит, но не сразу:
    this.$watch(() => this.$route, (x) => {
      this.length = this.$route.query.length;
      this.width = this.$route.query.width;
      this.height = this.$route.query.height;
    }, {deep: true, immediate: true});

    ИМХО, это баг и надо бы завести issue им на github.
    Ответ написан
    6 комментариев
  • Как хранить и востанавливать стор pinia в роутере?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Ну, грустно, что ты не использовал нормальный роутер изначально, а прилил свой костыль. Теперь у тебя два пути: переписать всё с использованием роутера или вкорячить ещё один костыль.
    Первое сложнее сейчас, но в дальнейшем куда проще в развитии.
    Второе быстрее сейчас, но чревато полной невозможностью поддержки в будущем.

    В первом случае понятно что делать, во втором - написать что-то с использованием history api. Что-то сложное и замороченное, учитывающее конкретно твоё приложение, с применением pushState и реакцией на popstate.
    Ответ написан
    Комментировать
  • Как узнать, что находится внутри slot?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Тебе ответили в общем, но в конкретном случае можно просто делать provide и inject в этом дровере. Если есть inject - значит где-то в родителях есть другой дровер и собсно через заинжекченое можно им управлять..
    Ответ написан
    Комментировать