Задать вопрос
Ответы пользователя по тегу Vue.js
  • Как выделить активный(выбранный) элемент на VUE?

    0xD34F
    @0xD34F Куратор тега Vue.js
    В родителе:

    data: () => ({
      activeElem: null,
      ...
    }),

    <Item
      :active="activeElem === elem"
      @activate="activeElem = elem"
      ...
    />

    В дочернем компоненте:

    props: {
      active: Boolean,
      ...
    },

    this.$emit('activate'); // когда надо сделать текущий элемент активным

    <div class="row__elements" :class="{ active }">
    Ответ написан
    4 комментария
  • Как разбить на адекватные vue компоненты?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сделать общий компонент с параметром, который будет определять количество значений, доступных для выбора:

    props: {
      multiple: Boolean,
      ...
    },
    computed: {
      placeholder() {
        return `Выберите ${this.multiple ? 'несколько значений' : 'одно значение'}`;
      },
      innerValue: {
        get() {
          const v = this.value;
          return this.multiple || this.options.includes(v) ? v : '';
        },
        set(val) {
          this.$emit('input', val);
        },
      },
    },

    <select v-model="innerValue" :multiple="multiple">
      <option disabled value="" v-text="placeholder"></option>
      <option v-for="n in options">{{ n }}</option>
    </select>

    https://jsfiddle.net/cgknyLd0/2/
    Ответ написан
    Комментировать
  • Как после добавления объекта в стор избежать ошибки "do not mutate vuex store state outside mutation handlers"?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Error: [vuex] do not mutate vuex store state outside mutation handlers.

    Ну да, как и должно быть. Вы же помещаете в массив, находящийся в хранилище, ссылку на объект, с которым работаете в компоненте с формой.

    Добавляя объект в хранилище, создавайте копию:

    this.$store.commit('vehicles/addVehicle', { ...this.vehicle });
    // или
    addVehicle: (state, payload) => state.vehicles.push({ ...payload }),


    Или заменяйте оригинал. Добавляете в компонент метод, создающий объект с дефолтными значениями свойств:

    methods: {
      createNewVehicle: () => ({
        name: '',
        description: '',
        rent: '',
        type: 'custom',
      }),
      ...

    Применяете его при создании объекта с данными экземпляра компонента и после вызова мутации:

    data() {
      return {
        vehicle: this.createNewVehicle(),
      };
    },

    this.$store.commit('vehicles/addVehicle', this.vehicle);
    this.vehicle = this.createNewVehicle();
    Ответ написан
    1 комментарий
  • Как правильно выводить данные при выборе radio?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Из массива с ценами надо выдернуть элемент, соответствующий выбранному индексу:

    <span>{{ result.prices[result.indexOfSize] }}</span>


    А вообще, что-то не могу никак понять - зачем раскладывать данные, относящиеся к одной сущности, по разным массивам? Я бы сделал массив объектов:

    items: [
      { size: '256GB', price:  '99 999' },
      { size: '512GB', price: '105 999' },
    ],
    index: 0,

    <label v-for="(n, i) in result.items">
      <input type="radio" :value="i" v-model.number="result.index">
      <span>{{ n.size }}</span>
    </label>

    Выбранный элемент которого можно оформить как вычисляемое свойство:

    computed: {
      selectedItem() {
        return this.result.items[this.result.index];
      },
      ...

    Ну и вывод цены станет выглядеть так:

    <span>{{ selectedItem.price }}</span>
    Ответ написан
    Комментировать
  • Почему исчезает плавный скролл, если добавить закрытие меню?

    0xD34F
    @0xD34F Куратор тега Vue.js
    @click="menuShow=!menuShow,goToBlock"

    Добавив переключение menuShow, вы превратили значение v-on из имени метода в inline-выражение. Так что goToBlock теперь не вызывается. Вызовем: @click="menuShow = !menuShow, goToBlock($event)". Ну а лучше бы конечно сделать новый метод (если goToBlock действительно нужен как отдельный метод, в противном случае достаточно унести в него переключение menuShow), как-то так:

    methods: {
      goToBlock(selector) {
        document.querySelector(selector).scrollIntoView({
          behavior: 'smooth',
        });
      },
      onMenuItemClick(e) {
        this.menuShow = false;
        this.goToBlock(e.target.getAttribute('href'));
      },
    },

    @click.prevent="onMenuItemClick"
    Ответ написан
  • Как отследить изменение во вложенном объекте data в vue2?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сделать вычисляемое свойство, содержащее в себе все need_watch:

    computed: {
      needWatch() {
        return Object.fromEntries(Object.entries(this.obj_lev_1).map(n => [ n[0], n[1].need_watch ]));
      },
    },

    И следить за ним:

    watch: {
      needWatch(newVal, oldVal) {
        const [ k, v ] = Object.entries(newVal).find(n => n[1] !== oldVal[n[0]]);
        alert(`${k}.need_watch changed from ${oldVal[k]} to ${v}`);
      },
    },

    Или, сделать компонент, который будет получать вложенные объекты или их need_watch в качестве параметра. Создавать новое значение внутри и отправлять его наверх (v-model/sync). Подписаться в родителе на соответствующее событие (вместо использования watch).
    Ответ написан
    Комментировать
  • Как передать значние input и изменить его в модальном окне?

    0xD34F
    @0xD34F Куратор тега Vue.js
    editTask (task, index) {

    v-model="editidTask.title"

    task.title = this.editTask.title

    Вижу, имена свойств/методов подобраны грамотно - перепутать невозможно.

    this.tasks.map((task, index) => {
      if (index === this.editidTask.id) {

    Во-первых - зачем перебирать массив, если вам известен индекс элемента? Кстати, очень умно - хранить индекс в свойстве с именем "id".

    Во-вторых - не боитесь обновить что-то не то? Работаете с массивом tasks, используя индекс, полученный при работе с tasksFiltered.

    UPD. Исправляем:

    При сохранении копируем свойства редактируемого объекта, а не метода, начинающего процесс редактирования (серьёзно, как можно было перепутать?).

    К чёрту индекс, всё равно удалять с его помощью не получится - для этого нужен индекс в исходном массиве, а не отфильтрованном. Ищем нужный элемент непосредственно в момент сохранения.

    Напрямую к заявленной проблеме не относится, но сказать стоит:

    Имеет смысл оформить модальное окно как отдельный компонент - упрощаем компонент с таблицей, получаем возможность переиспользовать окно в других местах. Содержимое (текстовые поля) передаём внутрь через слот.

    <list

    Почему list, если этот компонент работает с одним элементом массива? Не понимаете, в чём разница между "один" и "несколько"?

    :tasks="task"

    Почему tasks, если передаёте один объект? Повторю свой вопрос - не понимаете, в чём разница между "один" и "несколько"?

    :key="task.title"

    Что, одинаковых title'ов быть не может? Может. Пусть здесь вместо вводимого пользователем текста будет автоматически генерируемый id.

    v-show="isModal"

    Отдельное свойство для управления состоянием модального окна не нужно, достаточно редактируемого объекта - окно открывается, если он не null.

    task.date = this.editTask.date
    task.title = this.editTask.title

    Завтра потребуется редактировать третье свойство - будете копипастить? Перечислять вручную ничего не надо, есть же Object.assign.
    Ответ написан
  • Как запросить данные только если компонент виден на экране?

    0xD34F
    @0xD34F Куратор тега Vue.js
    mounted() {
      const observer = new IntersectionObserver(entries => {
        if (entries[0].isIntersecting) {
          stopObservation();
          // здесь запрашивайте свои данные
        }
      }, {
        threshold: 1,
      });
      observer.observe(this.$el);
    
      const stopObservation = () => observer.disconnect();
      this.$on('hook:beforeDestroy', stopObservation);
    },
    Ответ написан
    1 комментарий
  • Почему vue дублирует index?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Потому что вы используете компонент App дважды - как корневой компонент приложения, и как компонент маршрута.

    Уберите { path: '/', component: App },, или укажите вместо App какой-нибудь другой компонент.
    Ответ написан
    Комментировать
  • Всплывающий placeholder, как переписать с jQuery на Vue.js?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Вместо прямого добавления/удаления класса сделайте динамическую привязку в зависимости от текущего значения инпута. Чтобы упростить повторное использование, сделайте компонент: принимает в качестве параметров значение и плейсхолдер, при редактировании пользователем инпута выбрасывает соответствующее событие с новым значением.

    props: [ 'value', 'placeholder' ],

    <div>
      <input
        :class="value ? 'input_filled' : ''"
        :value="value"
        @input="$emit('input', $event.target.value)"
      >
      <span>{{ placeholder }}</span>
    </div>

    https://jsfiddle.net/2415wkmg/
    Ответ написан
    Комментировать
  • Как во Vue задействовать фильтр + сортировку одновременно?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сделать вычисляемое свойство, где будут выполняться все необходимые вам преобразования данных. Например.
    Ответ написан
    3 комментария
  • Как в v-treeview сделать корневой элемент постоянно открытым?

    0xD34F
    @0xD34F Куратор тега Vue.js
    data: () => ({
      opened: [],
      ...
    }),
    watch: {
      opened: {
        immediate: true,
        handler(val) {
          const id = this.treeitems[0].id;
          if (!val.includes(id)) {
            val.push(id);
          }
        }
      },
      ...
    },

    :open.sync="opened"
    Ответ написан
  • Как правильно использовать this в примесях работая с классом?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Привязать контекст заранее (bind), или указывать при вызове (call, apply).

    Разбираюсь, как устроен vuejs

    vue привязывает контекст заранее
    Ответ написан
    1 комментарий
  • Как при клике на дочерние элементы получить тот, на который был повешен обработчик события?

    0xD34F
    @0xD34F Куратор тега Vue.js
    в this экземпляр vue

    Как и должно быть - в качестве контекста вызова методов vue устанавливает экземпляр компонента. Что логично - иначе внутри метода было бы затруднительно получить доступ к другим свойствам/методам компонента.

    Используйте currentTarget.
    Ответ написан
    Комментировать
  • Как реализовать transition в render функции vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Ответ написан
    Комментировать
  • Как правильно сделать динамический v-model во Vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    дошел до "v-model изначально равным соответствующему значению из объекта data" и не понимаю как это сделать

    При создании массива, описывающего элементы формы, строки с путями к значениям режете на куски (разделитель - точка). Используя полученные массивы, достаёте из data значения, помещаете их в объекты, описывающие элементы формы. Всё, можно использовать v-model:

    <el-form-item v-for="n in formItems">
      <el-input v-model="n.value" />

    https://jsfiddle.net/3q706bp9/

    Если же хотите, чтобы при использовании v-model изменялись значения в data, то после разрезания строки с путём выдёргиваете из полученного массива последнее значение - это ключ, имя свойства. Объект, в котором это свойство находится, достаёте из data, основываясь на том, что в массиве осталось. Кладёте ключ и полученный объект в объект, описывающий элемент формы. А в шаблоне делаете так:

    <el-form-item v-for="n in formItems">
      <el-input v-model="n.obj[n.key]" />

    Поскольку объект в data и объект в объекте, описывающем элемент формы - один и тот же, то при изменении второго, будет меняться и первый.

    https://jsfiddle.net/x6ncpo90/
    Ответ написан
    Комментировать
  • Почему хук created срабатывает, но значение параметра в data не меняется?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сохраняете true/false, а читаете 'true'/'false'. В куках же строки хранятся. А булевым эквивалентом любой непустой строки является true. Поэтому результат работы v-if/v-show одинаков, вне зависимости от прочитанного значения.
    Ответ написан
  • Как сделать второй слайд основным?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Что значит "основной"? Показываемый при инициализации? Если так, то

    data: () => ({
      swiperOptions: {
        initialSlide: здесь номер слайда,
      },
    }),

    <swiper :options="swiperOptions">
    Ответ написан
    1 комментарий
  • Как передать data-value по клику в определенное место?

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

    data: () => ({
      value: '',
      values: [ 'hello, world!!', 'fuck the world', 'fuck everything' ],
    }),

    <input v-model="value">
    <button v-for="(n, i) in values" @click="value = n">set value #{{ i + 1 }}</button>
    Ответ написан
    Комментировать
  • Как менять высоту блока по мере прокрутки страницы во vuejs?

    0xD34F
    @0xD34F Куратор тега Vue.js
    data: () => ({
      scroll: 0,
    }),
    computed: {
      style() {
        return {
          height: здесь рассчитываете высоту на основе this.scroll,
        };
      },
    },
    created() {
      const onScroll = () => this.scroll = document.scrollingElement.scrollTop;
      onScroll();
      document.addEventListener('scroll', onScroll);
      this.$on('hook:beforeDestroy', () => document.removeEventListener('scroll', onScroll));
    },

    <div :style="style">
    Ответ написан
    1 комментарий