Ответы пользователя по тегу Vue.js
  • Почему не происходит вывод данных?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Консоль говорит, что не может найти product, потому что я не правильно использую хуки.

    Нет. Консоль вам говорит что-то другое.

    Вот эта вот строка,

    var prod = product;

    - что вы хотели ею сказать? Что ещё за product? Это который в data лежит? Тогда должно быть this.product. Почему вы пытаетесь определить переменную с таким же именем как и у параметра? А при вызове в хуке mounted - почему ничего не передаёте в метод results, у него же определён параметр?

    Думаю, должно быть так: строку, процитированную выше - просто удаляете, а в mounted при вызове results передавайте ему product - this.results(this.product). Или так: строку удаляете, удаляете параметр prod, в вызове axios.get вместо prod используете this.product.
    Ответ написан
  • Как во vuejs при событии в изолированном компоненте - потушить свойство в братских компонентах на одном уровне?

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

    0xD34F
    @0xD34F Куратор тега Vue.js
    при вводе каждого символа с поля слетает фокус

    Потому что при изменении значения поле создаётся заново - ведь вы в качестве key это значение и указали. Что само по себе является дичью несусветной, кроме того, так у вас могут быть поля с одинаковыми key.

    Генерируйте уникальные значения для key в момент добавления нового элемента в массив company_ids. Если удаление элементов из массива не предполагается, это может быть просто количество элементов / индекс элемента в массиве:

    this.form.company_ids.push({
      key: this.form.company_ids.length,
    });

    В противном случае можно сделать в компоненте свойство, значение которого будет при каждом добавлении увеличиваться:

    this.form.company_ids.push({
      key: ++this.currKey,
    });

    Или можно брать текущее максимальное значение key + 1:

    this.form.company_ids.push({
      key: Math.max(0, ...this.form.company_ids.map(n => n.key)) + 1,
    });
    Ответ написан
    1 комментарий
  • Как запретить выбор значений, которые не входят в группу?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сделаем метод, получающий item и возвращающий его группу:

    methods: {
      group(item) {
        return item && Object.entries(this.groups).find(([ k, v ]) => v.includes(item.group))[0];
      },

    Сделаем вычисляемое свойство, представляющее выбранную группу:

    computed: {
      selectedGroup() {
        return this.group([].concat(...this.data.map(n => n.items)).find(n => n.checked));
      },

    Если выбранная группа есть и не совпадает с группой текущего item'а, блокируем чекбокс:

    <ul v-for="{ items } in data">
      <li v-for="item in items">
        <label>
          <input
            type="checkbox"
            v-model="item.checked"
            :disabled="selectedGroup && selectedGroup !== group(item)"
          >
          {{ item.name }} ({{ group(item) }})
        </label>
      </li>
    </ul>

    https://jsfiddle.net/cqm1erza/
    Ответ написан
    Комментировать
  • Как сделать, чтобы checkbox уже был заранее нажат?

    0xD34F
    @0xD34F Куратор тега Vue.js
    • Вариант раз.

      Добавить элементам массива mainCategories свойства, которые будут отвечать за состояния чекбоксов (по умолчанию имеют значения true); массив checkedCategories сделать вычисляемым:

      data: () => ({
        mainCategories: [
          { merchantId: '1', checked: true },
          { merchantId: '2', checked: true },
          ...
        ],
      }),
      computed: {
        checkedCategories() {
          return this.mainCategories.filter(n => n.checked).map(n => n.merchantId);
        },
      },

      <li v-for="n in mainCategories">
        <label>
          <input type="checkbox" v-model="n.checked">
          {{ n.merchantId }}
        </label>
      </li>


    • Вариант два.

      При создании экземпляра компонента заполнить массив checkedCategories нужными значениями:

      created() {
        this.checkedCategories = this.mainCategories.map(n => n.merchantId);
      },


    Ответ написан
    Комментировать
  • Вообщем есть блок skills с процентами, как можно через vue вывести по количеству процентов линию?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Для начала опишем элементы списка в виде массива объектов, где текст и процент будут отдельными свойствами:

    data: () => ({
      items: [
        { name:      'PHOTOSHOP', val: 88, color:    'red' },
        { name:    'ILLUSTRATOR', val: 92, color:  'green' },
        { name:         'SKETCH', val: 90, color: 'orange' },
        { name: 'AFFTER EFFECTS', val: 98, color:   'blue' },
      ],
    }),

    Затем сделаем методы, который будут генерировать текст и стили для рисования линии (в качестве линии можно использовать границу элемента, border-bottom например) у элемента списка:

    methods: {
      liText: item => `${item.name} ${item.val}%`,
      liStyle: item => ({
        'border-bottom': `3px solid ${item.color}`,
        width: `${item.val}%`,
      }),
    },

    И, наконец, отрендерим список:

    <ul>
      <li
        v-for="n in items"
        v-text="liText(n)"
        :style="liStyle(n)"
      ></li>
    </ul>
    Ответ написан
    Комментировать
  • Как скрывать выпадающий список при выборе какого-либо его пункта?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Метод openClick - кто вас такой мерзости научил? Срочно читаем документацию, как правильно работать с классами. Но вообще, чтобы скрывать/показывать элементы, переключать классы необходимости нет - под это дело предусмотрен специальный инструмент.

    data: () => ({
      show: false,
      items: [ 'в сети', 'занят', 'отсутствую', 'в самолете', 'в пути' ],
      status: 'статус',
    }),
    methods: {
      selectStatus(status) {
        this.status = status;
        this.show = false;
      },
    },

    <div
      v-text="status"
      @click="show = !show"
    ></div>
    <ul v-show="show">
      <li
        v-for="n in items"
        v-text="n"
        @click="selectStatus(n)"
      ></li>
    </ul>
    Ответ написан
    Комментировать
  • Как управлять состоянием множества диалоговых окон (Vue, Vuex, Element UI)?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Передавайте в мутацию вместо просто состояния диалога объект вида { имя_диалога: состояние }. Тогда при обновлении состояния диалогов не будет необходимости обращаться к ним поимённо:

    mutations: {
      dialogShow: (state, payload) => Object.assign(state.modals, payload),
    },

    В компоненте, вместо вычисляемого свойства modal, отвечающего за работу с одним диалогом, будет свойство modals, обеспечивающее получение состояния всех диалогов. А чтобы изменение состояния диалога по-прежнему выглядело как присваивание, воспользуемся Proxy, где будем перехватывать установку значений и вызывать мутацию:

    modals() {
      return new Proxy(this.$store.state.modals, {
        set: (target, prop, value) => {
          this.$store.commit('dialogShow', { [prop]: value });
          return true;
        },
      });
    },

    Соответственно, в шаблоне заменяем установку значения просто свойства на установку значения свойства объекта:

    <el-button @click="modals.dialogSignIn = true">sign in</el-button>
    
    <el-dialog :visible="modals.dialogSignIn" @close="modals.dialogSignIn = false">
      <span slot="footer" class="dialog-footer">
        <el-button @click="modals.dialogSignIn = false">Закрыть</el-button>
      </span>
    </el-dialog>

    Посмотреть живьём.
    Ответ написан
    1 комментарий
  • Как правильно добавлять в canvas динамически созданное изображение?

    0xD34F
    @0xD34F Куратор тега Vue.js
    В Network указывается не jpeg, а text/html

    Путь неправильный. Или сервер файл не отдаёт. Вы бы посмотрели, что там в этом text/html - должно быть написано.

    Ну и зачем тут requestAnimationFrame - я без понятия. Выглядит бредово. Есть же обработчик onload - в нём и рисуйте:

    mounted() {
      const img = new Image();
      img.onload = () => this.$refs.canvas.getContext('2d').drawImage(img, 0, 0);
      img.src = '...';
    },

    https://jsfiddle.net/bd0ro2yL/
    Ответ написан
    Комментировать
  • Vue js, как показать option в select выбранный по умолчанию?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Указывать атрибут selected бессмысленно - v-model его игнорирует. Вместо этого, задайте свойству selectedSport в качестве начального значения пустую строку - как в value нужного вам option'а.
    Ответ написан
    1 комментарий
  • Не работает события у инпута который имеет атрибут disabled?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Не работает

    Всё правильно, так и должно быть. Чего ещё вы ожидали, вешая disabled?

    есть вариант решения?

    Решения чего? Что вы вообще пытаетесь сделать? Ничего не понятно.

    UPD. Вынесено из комментариев:

    Я хочу что бы у инпутов focus срабатывал только по клику

    Используйте readonly вместо disabled. Как-то так.
    Ответ написан
  • Как реализовать подзагрузку страницы перед переходом на нее в Vue JS?

    0xD34F
    @0xD34F Куратор тега Vue.js
    В интересующем вас компоненте определяете хук beforeRouteEnter - в нём и инициируете получение данных. Как оно конкретно выглядит - непосредственно выполнение запроса, или вызов экшена - тут вам виднее. После получения данных дёргаете next. Всё.

    UPD. Не, не всё. Если не очень поняли, о чём я - сделал небольшой пример. Три роута, первые два ни о чём, последний - показывает данные из хранилища. И при каждом переходе инициирует их обновление.
    Ответ написан
    Комментировать
  • Как реализовать смену цвета при клике в списке vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Раз у вас список - значит, наверное, за цвет каждого элемента должно отвечать отдельное значение, а не как у вас - одно на всех. Наверное, эти отдельные значения должны быть свойствами элементов массива, на основе которого разметка будет создаваться с помощью v-for, а не как у вас - вручную. Наверное, если элементы должны менять цвет независимо, соответствующий класс и обработчик клика должны назначаться самим элементам, а не как у вас - контейнеру.

    UPD. jsfiddle.net/42bfx93e
    Ответ написан
    Комментировать
  • Как настроить throttle/debounce в этом случае?

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

    Чтобы работало так, как вы хотите, popup в каждом отдельном экземпляре должен быть уникальной функцией, т.е. в methods ему не место:

    created() {
      this.popup = _.throttle(function(state) {
        this.show = ({
          enter: true,
          leave: false,
        })[state];
      }, 500, {
        leading: false,
        trailing: true,
      });
    },

    Ну и как-то громоздко выглядит. Может ну их, эти enter/leave:

    this.popup = _.throttle(show => this.show = !!show, 500, {
      leading: false,
      trailing: true,
    });

    <a href="#" @mouseenter="popup(1)" @mouseleave="popup(0)">

    ??
    Ответ написан
    3 комментария
  • Маска для поля ввода телефонного номера в vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    решил использовать фильтр

    Почему? Зачем? Вот вы выше говорите, что "есть много готовых плагинов" - так посмотрели бы, как там реализована подобная функциональность. Увидели бы, что для таких вещей применяются директивы. Как-то так, например.
    Ответ написан
    1 комментарий
  • Как сделать динамические импорты?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Понятно, что можно добавить в форму все виды инпутов и, например, использовать
    < component :is='нужный инпут в зависимости от пропса'>

    Вот так и поступите. Регистрируете все возможные компоненты, сделав их асинхронными.
    Ответ написан
  • Зачем передавать event в компонент Vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    зачем передавать: @my-event="myEvent" ?

    Правильнее говорить не "передавать", а "назначать обработчик события". Чисто технически - да, происходит передача функции в экземпляр компонента. Но поскольку способ передачи указывает на специфический способ использования этой функции, давайте будем придерживаться соответствующей терминологии.

    Итак, зачем назначать обработчик события? Вообще - это вам виднее, надо или не надо обрабатывать событие, и если надо, то как именно. А в данном конкретном случае - чтобы обновить значение свойства родительского компонента, отвечающего за состояние диалогового окна.

    Кстати,в явном виде делать это совсем не обязательно.

    Первый вариант - можно использовать модификатор sync при привязке значения параметра aa:

    <modal-notifications :aa.sync="isActive" :message="message"></modal-notifications>

    Метод закрытия в компоненте окна в этом случае станет выглядеть так:

    closeModalWindow() {
      this.$emit('update:aa', false);
    },

    Второй вариант - управлять состоянием окна посредством директивы v-model. Надо будет заменить имя параметра с aa на value (ну или настроить model):

    props: ['aa', 'message'], ---> props: [ 'value', 'message' ],
    :class="{'is-active': aa}" ---> :class="{ 'is-active': value }"

    Переписать метод закрытия окна:

    closeModalWindow() {
      this.$emit('input', false);
    },

    Ну а в родительском компоненте станет так:

    <modal-notifications v-model="isActive" :message="message"></modal-notifications>



    Я же делаю из потомка this.$emit('my-event', this.isActive) которое слушает родитель.

    Никто ничего просто так не "слушает". Чтобы "слушать", надо назначить обработчик соответствующего события. Что и происходит посредством @my-event="myEvent".

    эмит выше вроде бы не нужен, но без него не работает

    Чё? Какой ещё "эмит"? Нет "выше" никакого "эмита". Вы в родителе событие обрабатываете, а не порождаете.

    И еще вопрос. Что делает:
    myEvent: function(isActive) {
      this.isActive = isActive
    }

    Почему оно должно что-то принимать? Можно же просто значение из data взять.

    "Значение из data" брать бессмысленно - это и есть this.isActive. Который вам обновить надо. Обновить значением, которое присылает диалоговое окно. Значением, которое передаётся в (т.е., которое принимает) обработчик события.
    Ответ написан
    Комментировать
  • Как включить кнопку, если форма заполнена верно?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сделайте computed свойство, зависящее от наличия ошибок - и используйте это свойство как значение для disabled кнопки. Как-то так.
    Ответ написан
    1 комментарий
  • Почему в шаблоне не работает значение размещенное в data, а только props?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Всё работает. "Не работает" и "работает не так, как я ожидаю" - это не одно и то же.

    Назначение значения свойства на основе параметра осуществляется однократно - в data, при создании экземпляра компонента. Так что если хотите использовать в шаблоне именно свойство, вам его придётся обновлять вручную - вешайте watch на параметр.
    Ответ написан
  • Как динамически выводить элементы массива?

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

    obj() {
      return this.items[0];
    },

    Если он существует - выводим:

    <div v-if="obj">
      <div v-for="(val, key) in obj">
        ...

    Похоже на то, что вам надо?
    Ответ написан
    1 комментарий