Ответы пользователя по тегу Vue.js
  • Стоит ли учить только composition api?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Вопрос мутный как и весь vue 3. :)
    Если в React можно однозначно сказать ДА, с Vue, увы, так не получится, потому что много народу не отказалось и отказываться от options api не будет.

    Почему так? А потому, что в отличие от React - в vue options api на порядок удобнее и проще как в освоении так и в применении(особенно с классовыми компонентами), при том не имеет никаких действительно критических недостатков.
    Composition api же тут решают "проблему" которая и не встретится 99% пользователей(собственно завозит сложную перекрёстную композицию кусочков компонентов), при этом привносит кучу излишней сложности и микроконтроля(а также мерзкий синтаксис).

    Официальная позиция: composition api - будущее, всё остальное фигня. Большинство библиотек также ориентируется на composition api. На практике же этого будущего можно и не дождаться.:)

    В общем учи всё, благо более-менее просто.
    Ответ написан
    4 комментария
  • Почему v-on:keyup.enter и @:keyup.enter работают по-разному?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    @:click -> @click, соответственно, не: @:keyup.enter, а @keyup.enter

    Ну и не относится к проблеме, но красивее писать так:
    @click="add()" -> @click="add"
    Ответ написан
  • Как динамически передавать методы или переменные в компонент который рэндерится через v-for?

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

    И смотри-ка, всё работает.
    Проблема твоя где-то в другом месте.

    P.S. По-нормальному это делается как-то так:
    const thumbs = reactive([null, null, null]);
    v-for="(swiper, i) in thumbs" @swiper="thumbs[i]=$event" :thumbs="{ swiper }"

    Но может и ещё проще, если бы было больше контекста.:)
    Ответ написан
  • Как заставить Nuxt Image работать с изображениями из папки assets?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    С одной стороны для кастомных компонентов тебе потребовался бы transformAssetUrls. Однако открыв доки я вижу там:
    Converts src to provider optimized URLs

    В связи с чем вопрос: а путь то такой вообще работает?
    Что будет в img если ты делаешьimport img from '~/assets/images/header.jpg'?
    Ответ написан
    3 комментария
  • Как загрузить картинку в VUE3?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Подстановка путей к динамическим ассетам осуществляется на этапе сборки. Со строками из js сборка напрямую не работает.

    1. Ты можешь сделать так:
    import Wordpress from '../assets/wordpress-logotype-wmark.png';
    import Bitrix from '@/assets/logotip/1c_bitrix_logo.svg.png';
    const brandImgs = {
      '1C Bitrix': Bitrix,
      Wordpress,
    };

    По сути сделать руками то, что делает сборщик vue с src под капотом.

    2. Ты можешь просто сразу положить иконки в папку /public и указывать не относительные пути в рамках проекта, а абсолютные от корня:
    const brandImgs = {
      '1C Bitrix': '/logotip/1c_bitrix_logo.svg.png',
      'Wordpress': '/logotip/wordpress-logotype-wmark.png',
     };


    3. Ты можешь использовать динамический import().

    4. Ты можешь использовать import.meta.glob в vite или require.context в webpack.
    (Тут стоит помнить, что все ограничения упомянутые для п.3 применимы и здесь.)
    Ответ написан
  • Как правильно реализовать передачу данных между не связанными друг с другом компонентами в vue3?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Если ты не используешь SSR, то тебе достаточно просто reactive/ref объекта, чтоб получить эрзац-стор, тупо:
    // где-нибудь 
    export const basket = reactive([]); // или ref([]) по вкусу. 
    // везде где надо
    import { basket } from './...'

    Реактивность будет прекрасно работать.

    Почему кто-то использует специальные store если можно делать так? Потому что сторы учитывают работу в режиме SSR, а также позволяют удобную отладку в случае множества запутанных связей.
    Вам я бы тоже рекомендовал использовать таки store - только pinia, а не vuex. Не вижу причин его не использовать.

    По поводу EventBus: с одной стороны новичку её использовать категорически не рекомендуется, т.к. работа со store куда удобнее, очевиднее и надёжнее. Однако и совсем отрицать её использование тоже не следует, шина отлично подходит для случаев когда мы имеем дело именно с событиями, а не изменением состояния. Т.е. послать какой-нить notification или лог - самое оно, использовать для изменения basket, как в вашем случае - нет.
    Ответ написан
    1 комментарий
  • Как использовать директивы внутри кастомных директив в nuxt 3?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Встроенного механизма наследования нет. Директивы - это уже продвинутый механизм, подразумевается, что раз уж вы взялись за директивы - вы глубоко понимаете механизмы Vue. Если вам сильно хочется таки использовать чужую директиву внутри своей, надо будет самостоятельно экспериментировать, навскидку вижу два варианта:
    1. "тупой", но точно работающий - пробрасывать все возможные хуки директивы напрямую:
    const myDirective = {
      created(el, binding, vnode, prevVnode) {
         otherDirective?.created(el, binding, vnode, prevVnode);
         ...
      },
      beforeMount(el, binding, vnode, prevVnode) {
         otherDirective?.beforeMount(el, binding, vnode, prevVnode);
         ...
      },
      ....
    }

    2. "умный", но требующий знаний и экспериментов - манипуляции напрямую с vNode.

    Однако, возможно, лучше будет сделать просто-компонент-обёртку, который просто навесит все нужные директивы на обёрнутый компонент, примерно так:
    import { useSlots, withDirectives, resolveDirective } from 'vue'
    
    export default {
      setup() {
        const htmlDirective = {
          mounted(el, html) {
            el.innerHTML = html.value
          }
        }
    
        const colorDirective = {
          mounted(el, color) {
            el.style.color = color.value
          }
        }
        
        // const someDirective = resolveDirective('some-directive');
    
        const slots = useSlots();
    
        return () => withDirectives(slots.default()[0], [
          [htmlDirective, 'some html'],
          [colorDirective, 'red'],
        ])
      }
    }

    <wrapper><some-compnent /></wrapper>
    Ответ написан
    1 комментарий
  • Верный ли алгоритм для фильтра товаров?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Нормально. Источником состояния должно быть только одно место: в данном случае этим источником выступает url.
    Ответ написан
    Комментировать
  • Как удалить элемент массива при клике на кнопку?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    @click="deleteTodo(todo)"
    
    deleteTodo(todo) {
      this.todos.splice(this.todos.indexOf(todo), 1);
    }

    Или
    v-for="(todo, index) in todos"
    @click="deleteTodo(index)"
    
    deleteTodo(index) {
      this.todos.splice(index, 1);
    }
    Ответ написан
    Комментировать
  • Можно ли передавать CSS классы через props?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Передавать класс в props можно, многие библиотек так делают, но осторожно и только когда без этого не обойтись.

    Особенно стоит обратить внимание на это при использовании scoped стилей: переданный внутрь класс не будет работать сам по себе, т.к. привязан к scope родительского компонента, придётся использовать псвевдоселектор :deep(), а это уже чревато коллизиями.

    Лучше же разбить всё на максимально небольшие компоненты с простыми api конфигурации и повсеместно использовать слоты, чтобы такие вещи не требовались слишком часто.
    Ответ написан
    2 комментария
  • Как использовать typescript в шаблоне Vue 2?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Vue 2 не даёт использовать произвольный код в шаблонах, там код компилируется вместе с самим шаблоном отдельно от всей твоей системы сборки.

    В теории можно подсунуть свои обработчики в компилятор, но на практике когда до этого дошло и я начал рыть в эту сторону - появился vue 3 и я забил. Можешь порыть и забить и ты.:)

    В любом случае тайпкасты в шаблоне - моветон, пофикси изначальные типы и всё будет нормально. Ну или по-хардокору можно отрубить тайпчек в шаблонах в IDE.:)

    Использование методов\функций в шаблоне - тоже весьма плохо, и так делать крайне на рекомендуется: подготовь все данные в compunted и отдавай в шаблон только чистые и удобные для него(шаблона) данные.
    Если это сделать кажется сложно, то с большой вероятностью вы неправильно используете vue: в vue надо разбивать всё на минимальные компоненты(пусть даже в пяток строк), вот и тут разбейте на подкомпоненты и всё снова станет просто и приятно.

    А на богомерзкий jsx не переходи, а то те, кто после тебя проект продолжит, могут тебе и глаз подбить.:)
    Ответ написан
    Комментировать
  • Как сделать JS desktop приложение как сайт Vue js?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Это называется PWA(progressive web app).
    Как сделать - гугли отдельно, нормальный ответ не влезет в рамки вопросника.
    Ответ написан
    Комментировать
  • Как проверить наличие nuxt во vue3?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Можно с помощью getCurrentInstance, но не нужно(прочтите предупреждение по ссылке).
    Лучше расскажите зачем оно вам надо, а мы предложим лучшее решение. :)
    Ответ написан
    Комментировать
  • Почему не работает поиск по массиву из объектов?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Во-первых: вопрос не относится к vue, он о чистом js.
    Во-вторых: код рабочий, просто у вас, судя по всему, отсутствуют такие item, где одновременно были бы равны item.product.article, item.size и item.warehouse.id, т.к. только в таком случае ветка уйдёт в нужную вам сторону. Если логика предполагалась какой-то другой - уточняйте.
    Во-третьих: используйте, по возможности, для отдельно стоящих объектов reactive вместо ref, код чище и приятней будет.
    Ответ написан
    Комментировать
  • Деплой Vue.js на GitHub выдает ошибку?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Неплохо бы, чтоб в следующих своих вопросах ты прикладывал собственно КОД и тест ошибки.
    Я смог выковырять причину из собранного бандла, но тебе просто повезло, куда чаще мне(и 99% людей) так делать лень.

    Теперь, собственно, проблема:
    у тебя в коде есть несколько мест где используется подобная обработка событий:
    @side-emit="(side, id) => { 
        this.players[id].side = side; 
        ...
    }"

    Причина ошибки в том, что ты тут явно используешь this, а внутри шаблона он не нужен, т.к. либо раскрывается неявно автоматически, либо, в случае со <script setup>, не используется вовсе. Следует запомнить: никакого this в шаблонах.
    Вот так будет работать:
    @side-emit="(side, id) => { 
        players[id].side = side; 
        ...
    }"

    Почему работает в режиме разработки? Потому что во время разработки используется упрощённый режим сборки, который совершенно случайно делает доступным правильный this в данном конкретном случае. Просто так совпало.

    Ну и касательно кода: в данном случае использовано аж два антипаттерна, которые лучше вообще не употреблять:
    1. События компонента должны эмитить ровно одно значение. Да, vue позволяет эмитить и принимать сколько угодно значений, однако чаще чем следовало бы это приводит к плохому коду. Желательно придерживаться правила: одно событие - один payload, как в обычных событиях js.
    2. Не следует декларировать функции внутри шаблона. Шаблон сам по себе должен содержать минимальное количество кода. Да, vue позволяет использовать любой js в шаблоне, однако чаще чем следовало бы это приводит к плохому коду. В шаблонах следует использовать маленькие кусочки кода, условно: @side-emit="someValue = $event ? 1 : 2", а что-то сложнее просто выносить в метод компонента\composition функцию: @side-emit="onSlideEmit".
    Ответ написан
    1 комментарий
  • Как записать голосовое сообщение?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    На второй вопрос вам ответил Stalker_RED, ответ же на первый вопрос:
    потому что, даже после того как вы остановили MediaRecorder, сам аудио-поток(stream) у вас всё ещё захвачен и вы можете слушать его дальше.
    Чтобы остановить поток - надо остановить все трэки в нём, примерно так:
    function stopStream(stream) {
      stream.getTracks().forEach(
        (track) => track.readyState === 'live' && track.stop()
      );
    }


    P.S. К Vue вопрос отношения не имеет.
    Ответ написан
    Комментировать
  • Почему возникает ошибка Cannot read properties of null (reading 'hasOwnProperty')?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Ошибка точно не в этой строке, а в каком-то магическом коде.

    Почему оно возникает?
    С высокой вероятностью можно предположить, что:
    1. window.dataLayer уже существует.
    2. window.dataLayer.push переопределён или window.dataLayer является реактивным (vue?) массивом и отслеживает добавления.(что суть одно)
    3. При push вызывается некая функция, которая без всяких проверок на то что значение не пустое делает условно так: puhedValue.ecommerce.hasOwnProperty(...) на чём благополучно и падает.

    Что делать?
    Не добавлять объект, в котором ecommerce: null, эта хрень ожидает, что ecommerce будет объектом и никак иначе.

    Почему?
    Хз, читайте доки, наверняка там описано как делать надо и не надо(ну или наоборот НЕ описано подобного варианта с null, что тоже вариант).
    Ответ написан
  • Как при работе с Echo проверить имеется ли подключение к сокету или нет?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Что я делаю не так?

    Повторно инициализируете при монтировании, duh.

    Если оно должно быть инициализировано раз и навсегда - выносите в отдельный класс\функцию(или в стор), которая вместо повторной инициализации отдаст имеющийся экземпляр.
    Если должно инициализироваться для каждого компонента заново, то просто в отключайтесь в beforeUnmount.
    Ответ написан
    Комментировать
  • Как работает State Managment в nuxt 3?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    SSR-friendly - значит что ты не должен об этом думать, а за тебя подумает фреймворк и сделает всё интуитивно снаружи и правильно внутри.)
    Ответ написан
    Комментировать
  • Возрат значений из шини событий?

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

    Просто сделайте свой api нотификаций. Экспортируйте функцию, условно, notify которая вернёт инстанс со всем управлением и импортируйте где надо.

    Если зачем-то прям очень надо через шину(зачем?), то можно сделать так:
    bus.global.emit("notify", {
        msg: "New SMS code Requested, Success",
        timer: 30,
        uid: '<заданный рукамиидентификатор>'
    });

    и, опять же, импорт функции управления, типа notification.get(uid), специально для "сложных" случаев. Но это такое себе.
    Ответ написан
    Комментировать