Ответы пользователя по тегу Vue.js
  • Почему геттер напрямую false, а в объекте true?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Потому что консоль не клонирует объекты.
    false - значение на момент вывода console.log.
    true - значение на момент клика тобой на объект в консоли.
    Ответ написан
    Комментировать
  • Как спроектировать архитектуру проекта использующего Vue3 и API module pattern?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Ну так не надо делать кашу.)

    Используйте только то что нужно, когда нужно:
    Ответ на запрос к api нужен только в рамках компонента? Просто запрашивайте в рамках компонента.
    Ответ должен быть использован в нескольких не связанных местах? Используйте стор(pinia или любой иной).

    Как ты собрался "обернуть все запросы в composable" - непонятно. Composable нужны для работы с логикой компонента, запросы api никак с этим не связаны, они просто поставляют данные. Если с этими данными потом уже нужна какая-то хитрая работа - тогда можно делать composable, который просто внутри себя будет использовать твои отдельные api модули. Смешивать всё в кучу точно не нужно.

    P.S. Composable - это не какая-то особая тумба-юмба, если не очевидно, это просто обычные функции. От любых иных они отличаются только тем, что внутри себя используют vue-хуки(тоже просто функции), а потому привязаны к компоненту внутри которого вызываются и не могут работать вне компонента.

    P.P.S. Те кто рекомендуют пихать запрсы в стор - долбоёбы. Были во времена vue2 остались и сейчас. Стор - это хранилище, он хранит. Работа с api должна быть от него отделена, иначе получится каша.
    Ответ написан
    1 комментарий
  • Не могу понять почему Vuex отдаёт пустой список в компонент Vue, в чём моя ошибка?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    С Vue и Vuex проблем нет.
    Вместо import getPRoducts напиши
    const getPRoducts = async () => {
      return [1, 2, 3]
    }
    и сможешь в этом убедиться.

    Проблема с твоим "сервисом" запросов. Смотри в консоль - он вообще работает, у тебя настроен cors, чтоб запрашивать с других портов? Если нет, то и не настраивай - используй devserver proxy и обращайся по относительным ссылкам как это будет и в проде.
    Ответ написан
    Комментировать
  • Как правильно стилизовать сторонние компоненты в Vue.js?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Ответ: по ситуации. :)

    В идеальном мире: сторонние компоненты должны поддерживать всю возможную стилизацию стандартизированным образом: либо через props, либо (реже и хуже) через документированные классы разрешённые к изменению сверху. В ином случае всегда будет оставаться шанс, что всё развалится при обновлении компонента.

    Теперь собственно к нашему, катящемуся в бездну, миру: да, смотреть шаблон компонента и менять стили через :deep или глобально. Обязательно писать к этому тесты, чтобы отвал после какого-то обновления не пролез незаметно на прод.
    Если править классы становится слишком сложно, то форкать к себе, и править как хочешь. Также можно форкнуть если компонент простой.

    Обратно к идеальному миру: при желании можно попробовать пропихнуть пул реквест автору оригинального компонента, поддерживающий нужную кастомизацию(естественно в универсальном и удобном виде).
    Ответ написан
    Комментировать
  • Как отсортировать массив элементов?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Чтоб сортировать весь массив - надо сортировать весь массив.
    v-for="(item, index) in currentPageSortedList"
    data: {
      list: [...bread[0]], // или просто bread? х.з. не ясно, что там
      // ...
    },
    computed: {
      sortedList() {
        const sort = {
          "По популярности": "changePopular",
          "По возрастанию цены": "changePlus",
          "По уменьшению цены": "changeMinus",
          "Сначала обсуждаемые": "changeDiscussed",
          "Сначала с лучшей оценкой": "changeBest"
        }[this.selected];
        // лишний slice здесь для того чтобы клонировать массив
        // т.к. sort мутирует исходный  
        return sort ? this.list.slice().sort(this[sort]) : this.list;    
      },
      currentPageSortedList() {
        const perPage = 6;
        const position = this.currentPage * perPage;   
        
        return this.sortedList.slice(position, position + perPage);;
      },
      // ...
    },
    watch: {
      // при смене выбора скидываем на первую страницу
      selected() {
        this.currentPage = 0;
      }
    }
    Ответ написан
    4 комментария
  • Ошибка Pinia, в чем проблема?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    useStore() как и любой хук(useX) надо использовать внутри setup секции компонента.

    В данном случае это нужно для того, чтобы получить store именно этого app(на станице может быть несколько app, каждый со своим store).
    Ответ написан
    Комментировать
  • Как исправить ошибку eslint на события мыши?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Чтобы исправить эту и многие иные ошибки надо включить мозг. Прям остановиться, нажать кнопку power on, и таки прочитать: кто тебе пишет, что тебе пишет, почему он тебе такое пишет.

    Итак:
    Кто тебе пишет? Пишет тебе набор правил vuejs-accessibility(vuejs-доступность по нашему). Этот набор правил сам по себе появиться не мог, он ставится дополнительным плагином. Если ты не знаешь откуда он у тебя взялся и тебе плевать на всяких инвалидов - можешь смело удалить этот плагин из eslint и забыть.

    Что тебе пишет? Коли по-басурмански ты не разумеешь, то тебе поможет гугл-транслейт:
    1. @mouseout или @mouseleave должны сопровождаться @focusout или @blur для доступности.
    2. @mouseover, @mouseenter или @hover должны сопровождаться @focusin или @focus для доступности.

    Почему он тебе такое пишет? Вот тут запускай свой мозг на все 146% и начинай по-нстоящему думать. Почему же совместно с @mouseenter нам может понадобится @focusin, если нам это советует правило по доступности? Думай, думай...
    Может быть для того, чтобы человек без возможности оперировать мышью смог таки с помощью клавиатуры вызвать связанные события, мм? И небольшое дублирование кода, которое поможет таким людям, совсем не страшно.

    P.S. Пока не выключен мозг - подумай ещё:
    1. К каким последствиям приведёт бездумное (лишь-бы-eslint-заткнулся) добавление одновременно @focus и @focusin?
    2. Не будет ли конфликтов внутри функций в случае получения элементом фокуса таки мышкой?
    ...
    Ответ написан
    Комментировать
  • Почему не применяются стили?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Если исправить все "технические" ошибки, которых у тебя тонна - то в самом коде Vue всё в порядке и переключение работает. :)

    Ошибки из-за которых оно вообще не должно собираться, а должно всю консоль исписать:
    1. Лишний закрывающий </div> в <template>.
    2. v-on: mouseover="out" должно быть слитно v-on:mouseover="out".
    3. Экспортируемый объект у тебя закрывается после data, methоds висят в воздухе.
    4. Не <styles>, а <style> причём судя по вложенности не просто <style>, который ожидает обычный css, а <style lang="scss">.

    Потенциальные ошибки:
    1. Отсутствие методов out и select.
    2. Отсутствие у <a> href="#" или, лучше, v-on:click.prevent из-за чего клик по ссылке открывает новую вкладку. А ещё лучше - не использовать <a> не для сссылок.
    3. Скорее всего ты хочешь, чтобы в случае если one - стока, то назначался класс из этой строки, а не класс .one, в таком случае выглядеть это должно так: v-bind:class="[one, { stels: stels }]" или, хуже, v-bind:class="{ [one]: one, stels: stels }".

    В целом: мужик, используй IDE, она тебе всё это заранее подчеркнёт; например VSCode абсолютно бесплатна.
    Ответ написан
    Комментировать
  • Как лучше сделать авторизацию в NUXT?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Про "очень просто" ты меня сейчас сильно насмешил. Тот же OAuth - это просто адище под капотом. Но даже в basic auth есть куча мелочей на которых можно запороться.
    В общем использовать само собой следует либу, сам ты гарантировано словишь тонну багов и дыр в безопасности, только выбирать более-менее приличную(на глазок - больше 1000 Weekly Downloads на npmjs.com и от не вызывающего подозрений автора).

    Со стороны nuxt очевидно лучше всего подойдёт https://auth.nuxtjs.org/ , со стороны laravel - хз, гугли реализацию одного из вариантов поддерживаемых auth.nuxtjs.

    Ну и прекратят поддержку либы скорее всего задолго после того как ты прекратишь поддержку и обновление разрабатываемого приложения.:)
    Ответ написан
    Комментировать
  • Для чего добавляется окончание View в название компонента?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    В vue не должно быть "одноименных" компонентов, чтоб случайно не перекрыть какой-нить новый html6 тег, вот и придумывают всякое:)

    В данном конкретном случае постфикс View добавлен к тем компонентам, которые являются "шаблонами" страниц верхнего уровня в системе маршрутов роутера.
    Т.е. они, скорее всего, существуют в единственном экземпляре, а не являются множественно используемым компонентом, и всякая динамика уже происходит на уровень ниже.

    Это не является какой-то утверждённой системой, например во многих случаях используется система: Layout - для подобных шаблонов, Page - для конкретных вложенных страниц.

    В целом vue ничего в этом плане не оговаривает, потому каждый делает как ему приятнее или как оговаривает конкретный фреймворк.
    Ответ написан
    2 комментария
  • Как решить ошибку TS в атрибуте name для input type = radio?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Ну name ждёт стрингу и не ждёт намбер, что тут непонятного?)
    "Правильно" - сделать как-то так :name="`${modelValue}`", но я бы попатчил типы инпута ибо он сам себе всё прекрасно преобразует.
    Ответ написан
    Комментировать
  • Как сделать на vueJs 3 похожий эффект как jQuery slideToggle?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    На чистом vue 3 это делается как-то так:


    Мб тут можно как-то добавить tailwind, тут уж сам смотри.
    Ответ написан
    3 комментария
  • Как правильно разрушить и инициализировать Swiper?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Как и с любым иным компонентом vue - не через залезание руками в api\dom.
    Просто делаете v-if="showSwiper" и переключаете, соответственно, this.showSwiper. Если v-if="false" компонент будет разрушен и всё.

    // Нормальные компоненты производят всю необходимую очистку внутри себя сами по автоматическому хуку destroy, и вам не надо не о чём заботиться. Иногда конечно встречается кривое г-но с текущей памятью, но в таких случях проще самому написать компонент с нуля.

    P,S. Никогда не используйте в одном компоненте одновременно setup и methods, вообще никогда. Либо одно либо другое. Это разная парадигма.
    Ответ написан
    5 комментариев
  • Встроить созданный на Vue.js видео плеер в wordpress, есть ли смысл и как это сделать?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Vue прекрасно поддерживает встройку куда угодно, просто подключаете на странице в script umd версию и тупо делаете mount в нужный dom-элеемент. Никакие фреймы не нужны. Только стили саого компонента огородите от перемешивания с местом встраивания, например с помощью БЭМ и\или префиксов.

    А ещё лучше - сделать из vue-компонента - web-component, если ориентация идёт на современные бразуеры. Тогда стили вообще будут инкапсулированы, а управление можно вынести в обычные html-аттрибуты.
    Ответ написан
    Комментировать
  • Не удается найти модуль "./App.vue" или связанные с ним объявления типов. Vue.js 3 и TypeScript?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Стандартная какашка, которая идёт в комплекте с любым готовым пресетом, файлик vue.d.ts с содержимым:
    declare module '*.vue' {
      import type { DefineComponent } from 'vue';
      const component: DefineComponent<{}, {}, any>;
      export default component;
    }
    Ответ написан
    Комментировать
  • Как удалить параметр по значению?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Если используешь функции из моего предыдущего ответа, то вот те дополнительные:

    // удаляет значение
    function removeFieldValue(previous, value) {
      if (!previous)
        return '';
      if (typeof value !== 'string')
        value = String(value);
    
      const uniqueValues = splitFieldValues(previous);
      uniqueValues.delete(value.trim());
    
      return [...uniqueValues].join(' ');
    }
    
    // удаляет значение по его порядковому номеру
    function removeFieldValueByIndex(previous, index) {
      if (!previous)
        return '';
    
      const uniqueValues = [...splitFieldValues(previous)];
      uniqueValues.splice(index, 1);
    
      return uniqueValues.join(' ');
    }


    Но всю программу ты чисто на вопросах не напишешь. (Нет, не напишешь.)
    Ответ написан
    Комментировать
  • Как добавить параметры в query?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Нужна - сделайте. Это элементарный javascript, vue тут не при чём.
    типа этого
    function concatenateFieldValue(previous, value) {
      if (typeof value !== 'string')
        value = String(value);
      if (!previous)
        return value;
    
      const uniqueValues = splitFieldValues(previous);
      uniqueValues.add(value.trim());
    
      return [...uniqueValues].join(' ');
    }
    
    function splitFieldValues(values) {
      return new Set(values.split(' ').filter(Boolean));
    }
    
    function getUpdatedQuery(query, field, value) {
      return {
        ...query,
        [field]: concatenateFieldValue(query[field], value)
      }
    }
    
    
    this.$router.push({
      query: getUpdatedQuery(
        this.$route.query, 
        itemNameParent, 
        e.target.value
      )
    });
    Ответ написан
    Комментировать
  • Как правильно подгружать динамические изображения во Vue.js?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    require работает на этапе компиляции. Т.е. во время исполнения он уже должен был собрать все вызовы require и положить их в .js файл. require не может быть динамичным, потому что на этапе исполнения его тупо уже нет - он заменён на то, что он возвращает.

    Для решения подобных задач два варианта:
    1. require.context - который соберёт все файлы по предоставленному шаблону на этапе компиляции, и на этапе исполнения будет их подставлять. Этот вариант подходит если в папке img уже сейчас лежат все нужные изображения.
    2. Если изображения на этапе компиляции отсутствуют, а появляются каким-то сторонним образом в паке потом, то require тебе тут не нужен(и не поможет), просто динамически подставляй пути к ним как в твоём первом варианте.
    Путь от корня, если что, можно получить из __webpack_public_path__:
    root: __webpack_public_path__,
    <img :src="root + 'img/' + message.filename" :alt="message.filename"/>
    Ответ написан
    4 комментария
  • Как получить значение внутри функции при нажатии кнопки?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Если changeTab не может примать async функцию(функцию возвращающую Promise) то никак. Ожидание действия пользователя - асинхронная операция. Тебе надо изменить логику поведения.

    Иначе: система диалогов должна быть в любом случае вынесена в отдельный компонент, а в идеале вообще во внутренние вызовы, типа:
    const result = await modal({
      title: ...,
      type: 'confirm',
      acceptText: 'Подтвердить',
      ...
    })


    Но если что-то колхозить, то условно так:
    showPopup() {
      this.isDialogShown = true;
      this.pending = new Promise((resolve) => {
        this.discardChanges = () => resolve(false);
        this.saveChanges = () => resolve(true);
      });
    },
    async changeTab() {
      ...
      return await this.pending;
    }

    Ну или прямо так:
    changeTab() {
      return new Promise((resolve) => {
        this.discardChanges = () => resolve(false);
        this.saveChanges = () => resolve(true);
      });
    }


    Но я бы так делать не стал, а таки вынес нормально всё, ибо один компонент должен выполнять ровно одну функцию и его логика не должна просачиваться в иные.
    Ответ написан
    4 комментария
  • Как сравнить значение с ключом объекта?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Твой index - и есть в данном случае ключ. Т.е. проверять нужно просто index === 'dateTime'.

    Опережая возможный вопрос - если тебе нужен именно цифровой индекс, то в случае с объектом на входе он будет третьим параметром:v-for="(filter, key, index) in filters". Однако в твоём случае он не нужен, т.к. лучше привязывать key именно к ключу.

    В vue всё для людей.)
    Ответ написан
    1 комментарий