Задать вопрос
Ответы пользователя по тегу Vue.js
  • Вообщем есть блок 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'а.
    Ответ написан
    2 комментария
  • Не работает события у инпута который имеет атрибут disabled?

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

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

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

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

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

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

    Используйте readonly вместо disabled. Как-то так.
    Ответ написан
  • Как заполнить объект из другого объекта свойствами, отмеченными в первом?

    0xD34F
    @0xD34F Куратор тега Vue.js
    arr.map(n => ({
      ...n,
      items: n.items.filter(m => m.checked).map(m => ({ ...m })),
    }))

    возможно, computed надо высчитывать?

    Если при изменении исходного массива должен обновиться массив c отмеченными элементами, то да, надо:

    computed: {
      checkedArr() {
        return this.arr.map(/* ... */);
      },
    },
    Ответ написан
    6 комментариев
  • Как реализовать подзагрузку страницы перед переходом на нее в 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 комментарий
  • Динамичская загрузка и рендеринг компонента?

    0xD34F
    @0xD34F Куратор тега Vue.js
    new Vue({
      router,
      store,
      components: {
        AppModile: () => import('@/AppMobile.vue'),
        App: () => import('@/App.vue')
      },
      render: h => h(isMobile ? 'AppMobile' : 'App')
    }).$mount('#app')
    Ответ написан
    Комментировать
  • Vuex для каталога с корзиной - как лучше реализовать такое решение?

    0xD34F
    @0xD34F Куратор тега Vue.js
    получать данные для корзины - в actions, через Promise.all по id вытаскивая данные для каждого товара?

    В смысле - хранить в cartItems только id (ну ещё количество и цену), а при каждом заходе пользователя в корзину подтягивать остальные данные (название/производитель/гарантия/...)? Во-первых, что ещё за Promise.all - собираетесь ради каждого товара выполнять отдельный запрос? Так дела не делаются - передавать на сервер следует массив id, запрос должен быть один. Во-вторых - получится, что у вас есть в хранилище массив id, а в компоненте корзины локально лежат полные данные товаров. На мой взгляд - как-то сложновато, при манипуляции данными cartItems из компонента корзины последний придётся вручную поддерживать в актуальном состоянии - watch на cartItems, отфильтровывание из локального массива удалённых элементов, копирование количества существующих.

    Короче, я при добавлении товара в корзину просто полностью бы копировал в cartItems данные из products.
    Ответ написан
    2 комментария
  • Как сделать чтобы при v-for класс добавлялся и убирался только по клику на данный элемент?

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

    todos: [
      { open: false, ... },
      { open: false, ... },
      ...
    ],

    По клику переключать значение этого свойства:

    @click="todo.open = !todo.open"

    Назначать класс в зависимости от значения:

    :class="{ 'dropdown-active': todo.open }"

    https://jsfiddle.net/2ef8yojn/
    Ответ написан
  • Как подключить google map в vue проект?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Правильно ли подключаю карту

    Конечно же нет - документацию вы явно не читали. Это зря. Вот вам правильно подключенная карта - сравнивайте как было, как стало, думайте, читайте документацию.
    Ответ написан