Ответы пользователя по тегу Vue.js
  • Как добавить свойство checked по условию входящих данных?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    У тебя проблема не в vue, а в базовом html:
    Оба input у тебя получают одинаковый id и оба label одинаковый for. Поведение браузера при клике на label в таком случае не определено, но на практике это значит, что клик идёт всегда первому input.

    Соответственно надо сделать либо так:
    <label class="form-check-label">
      <input 
        type="checkbox" 
        role="switch"
        v-model="methodId"
        :value="method.id"
        class="form-check-input" 
      />
      {{ method.name_method }}
    </label>

    Либо как-то так:
    <input 
      :id="`input-${method.id}`" 
      type="checkbox" role="switch"
      v-model="methodId"
      :value="method.id"
      class="form-check-input" 
    />
    <label :for="`input-${method.id}`" class="form-check-label">
      {{ method.name_method }}
    </label>
    Ответ написан
    1 комментарий
  • Как бороться с race condition при обращении к REST API во Vue?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Просто не давть пользователю повторно тыкать там, где это вызовет повторный запрос, пока идёт загрузка текущего?

    Но если хочется быть ленивым - можно просто обернуть запросы в leading debounce-promise.

    Все эти thunk и saga - полная ересь, порождённая богомерзким redux.
    Ответ написан
  • Возможно ли подключить к Vue стороний бандл с jquery?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Можно, просто вызывай свой init в mounted. Но нюансов множество.
    Ответ написан
  • Как перехватить перезагрузку страницы средствами JavaScript во Vue.js 3?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Никак. Пользователь сам решает, что ему делать.
    Ты можешь только запилить большую красивую кнопку "Обновить", чтоб ему захотелось нажать на неё, а не на стандартную.:)
    Ответ написан
  • Стоит ли учить только 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 комментарий