Задать вопрос
Ответы пользователя по тегу Vue.js
  • Select/option во Vue computed. Как использовать?

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

    <select v-model="selected">
      <option v-for="item in options" :value="item.value">
        {{ item.title }}
      </option>
    </select>

    data: () => ({
      selected: null,
      ...
    }),
    computed: {
      monthRate() {
        if (this.selected === 'year') {
          return this.percent / 12 / 100;
        } else if (this.selected === 'month') {
          return this.percent / 100;
        } else {
          return 0;
        }
      },
    },

    UPD.

    нужно, чтобы в зависимости от выбранной опции, функция срабатывала по разной формуле

    А насколько разной? То, что есть сейчас, можно значительно упростить: в качестве value вместо строк будут числа, напрямую подставляемые в формулу - 1/12 для year, 1 для month, 0 для остальных. Тогда вычисляемое свойство станет гораздо короче:

    monthRate() {
      return this.percent * this.selected / 100;
    },
    Ответ написан
    5 комментариев
  • Как добавить стиль при нажатии на элемент?

    0xD34F
    @0xD34F Куратор тега Vue.js
    .dropdown-checkbox ul.opened {
      display: block;
    }

    <label @click="opened = !opened">click me</label>
    <ul :class="{ opened }">
      ...

    data: () => ({
      opened: false,
    }),
    Ответ написан
    5 комментариев
  • Как использовать vue-i18n внутри script?

    0xD34F
    @0xD34F Куратор тега Vue.js
    computed: {
      msg() {
        return this.$t('welcomeMsg');
      },
    },
    Ответ написан
    Комментировать
  • Как заставить beforeRouter дождаться пока в firebase подтвердит авторизацию?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Поменяйте порядок действий - сначала авторизация, потом создание экземпляра vue:

    firebase.auth().onAuthStateChanged(user => {
      if (user) {
        store.dispatch('loggedUser', user);
      }
    
      new Vue(...);
    });
    Ответ написан
    1 комментарий
  • Почему внутри компонента не выводится свойство, а за пределами все норм?

    0xD34F
    @0xD34F Куратор тега Vue.js
    <script type="text/x-template" id="tree-template">
        {{ item }}
    </script>

    Что, просто текст? Нет, так не будет. Должен быть какой-то элемент. Сделайте li - вы же внутри ul пытаетесь их выводить:

    <script type="text/x-template" id="tree-template">
      <li>{{ item }}</li>
    </script>

    <ul v-for="item in items" :key="item.id">
                <tree-items
                        :item="item"
                ></tree-items>
            </ul>

    Множество списков с одним элементом? Может, должен быть один список с множеством элементов? - переносим v-for внутрь списка (кстати, а какого чёрта в имени компонента элемента списка множественное число? почему items, а не item?):

    <ul>
      <tree-items
        v-for="item in items"
        :key="item.id"
        :item="item"
      ></tree-items>
    </ul>
    Ответ написан
  • Как создать вложенный список из объекта Vue?

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

    0xD34F
    @0xD34F Куратор тега Vue.js
    <div ref="map">

    mounted() {
      this.map = L.map(this.$refs.map).setView([ 55.75222, 37.61556 ], 13);
      ...
    Ответ написан
  • Как повесить клик на строчку в таблице?

    0xD34F
    @0xD34F Куратор тега Vue.js
    <v-data-table @click:row="onClickRow">

    methods: {
      onClickRow(item) {
        console.log(item);
      },
      ...
    Ответ написан
    2 комментария
  • Как каждому из экземпляров Vue назначить отдельный Store?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Если воспользуетесь конструктором Vuex.Store более одного раза, вас за это в тюрьму не посадят. Так что вам ничего не мешает создать несколько разных сторов, свой для каждого экземпляра Vue.

    А если их структура должна быть идентична - сделайте функцию, которая будет создавать стор и вместо

    new Vue({
      store: store,
      ...

    будет

    new Vue({
      store: createStore(),
      ...

    https://jsfiddle.net/25L08xj1/
    Ответ написан
    Комментировать
  • Как управлять параметром для отдельного элемента DOM из Vue.js компонента?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сделайте отдельный компонент для этих секций, со свойством isActive - у каждого экземпляра оно будет собственное. Или этих isActive'ов у вас должен быть массив, длина которого равна количеству секций. Или добавьте свойство isActive элементам sections - каждому.
    Ответ написан
    5 комментариев
  • Как отрефакторить computed методы во Vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    передавать параметры <...> оставив в computed

    А смысл? Будет computed свойство, значение которого является функцией. Никакого кеширования, только усложнение кода. Делайте обычный метод:

    methods: {
      filterHeroes(attr) {
        const s = this.searchHeroesString.toLowerCase();
        return this.heroes.filter(n => n.hero_attribute === attr && n.name.toLowerCase().includes(s));
      },
    Ответ написан
    Комментировать
  • Как сделать скрытие блока, при клике на любую область?

    0xD34F
    @0xD34F Куратор тега Vue.js
    data: () => ({
      active: false,
    }),
    created() {
      const onClick = e => this.active = this.$refs.block.contains(e.target) && this.active;
      document.addEventListener('click', onClick);
      this.$on('hook:beforeDestroy', () => document.removeEventListener('click', onClick));
    },

    <button @click.stop="active = !active">click me</button>
    <div :class="{ active }" ref="block">hello, world!!</div>
    Ответ написан
    1 комментарий
  • Как при клике на кнопку в блоке открывать модальное окно/выезжающий сайдбар с данными того блока, в котором находиться кнопка?

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

    state: {
      opened: null,
      ...

    В экземпляры компонента Trigger передавайте соответствующие им блоки:

    <Trigger :block="block">

    props: [ 'block' ],

    Также, Trigger должен знать, какой блок открыт:

    computed: mapState([ 'opened' ]),

    Чтобы можно было назначить класс кнопке:

    :class="{ 'active' : block === opened }"

    При клике на которую следует передавать блок в мутацию:

    @click="toggleNav(block)"

    Мутация же будет устанавливать значение выбранного блока:

    toggleNav(state, block) {
      state.opened = state.opened === block ? null : block;
    },

    Это если оно действительно toggle. Если просто открытие - тогда достаточно state.opened = block (название мутации в этом случае конечно следует поменять).

    Мутация, отвечающая за закрытие, будет выглядеть так:

    closeSidebarPanel(state) {
      state.opened = null;
    },

    Геттер isNavOpen тоже изменится:

    isPanelOpen(state) {
      return !!state.opened;
    },

    Ну и наконец, можно что-нибудь вывести в Sidebar, например:

    <span v-if="isPanelOpen">{{ $store.state.opened.bName }}</span>

    Но если Sidebar предназначен конкретно для этих блоков, наверное, разумнее будет, чтобы он сам знал, кто сейчас открыт. В Sidebar'е цепляете opened к слоту:

    <slot :block="$store.state.opened"></slot>

    Соответственно, в родительском компоненте:

    <template #default="{ block }">
      <div class="sidebar-panel-settings">
        <div class="setting-block">
          {{ block.bName }}
        </div>
      </div>
    </template>
    Ответ написан
    1 комментарий
  • Как вывести data-attr?

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

    <select v-model="selected">
      <option v-for="n in deliveryPrice" :value="n">{{ n.city }}</option>
    </select>

    Ну и выводите чего хотите без проблем:

    <div v-if="selected">
      <div>{{ selected.city }}</div>
      <div>{{ selected.priceFrom }}</div>
    </div>


    Если вдруг напрягает [object Object], отображаемый в качестве value в разметке, то v-model пусть по-прежнему с примитивными значениями работает, а выбранный объект оформляем как computed свойство:

    <select v-model="city">
      <option v-for="n in deliveryPrice">{{ n.city }}</option>
    </select>

    computed: {
      selected() {
        return this.deliveryPrice.find(n => n.city === this.city);
      },
    },

    или

    <select v-model="selectedIndex">
      <option v-for="(n, i) in deliveryPrice" :value="i">{{ n.city }}</option>
    </select>

    data: () => ({
      selectedIndex: -1,
    }),

    computed: {
      selected() {
        return this.deliveryPrice[this.selectedIndex];
      },
    },
    Ответ написан
    1 комментарий
  • Как бесконечно проходить по массиву с задержкой?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Чем setInterval не устроил?
    let index = -1;
    setInterval(() => {
      index = (index + 1) % array.length;
      console.log(array[index]);
    }, 500);

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

    Показалось будет неудобно юзать в Вью компоненте. Мне надо при наведении мышки показывать по кругу картинки из массива и останавливать при убирании мышки.

    Не вижу ничего неудобного:

    <div
      @mouseenter="установитьИнтервал"
      @mouseleave="сброситьИнтервал"
    >

    methods: {
      установитьИнтервал() {
        this.interval = setInterval(() => { ... }, 666);
      },
      сброситьИнтервал() {
        clearInterval(this.interval);
      },
    },
    Ответ написан
    2 комментария
  • Как организовать опрос, как на tj?

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

    data: () => ({
      questions: [
        {
          text: '2 x 2?',
          answers: [ '5', '3', '69', '187' ],
        },
        {
          text: '...',
          answers: [ '...', '...', ... ],
        },
        ...
      ],
    }) ,

    Компонент вопроса.
    Принимает три параметра - текст вопроса, массив вариантов ответа, и выбранный ответ:

    props: [ 'text', 'answers', 'value' ],

    Показываем текст вопроса; на основе массива ответов создаём радиокнопки, если ответ совпадает с выбранным, соответствующая кнопка помечается как выбранная; при выборе кнопки отправляем значение родительскому компоненту:

    <div>{{ text }}</div>
    <div v-for="n in answers">
      <label>
        <input
          type="radio"
          :checked="n === value"
          @change="$emit('input', n)"
        >
        {{ n }}
      </label>
    </div>

    Компонент опроса.
    Принимает список вопросов в качестве параметра:

    props: [ 'questions' ],

    Из данных содержит в себе индекс текущего вопроса и массив выбранных ответов:

    data: () => ({
      index: 0,
      answers: [],
    }),

    Если индекс меньше количества вопросов, значит опрос ещё не окончен, показываем вопрос, в противном случае следует отобразить результаты:

    <div v-if="index < questions.length">
      вопрос
    </div>
    <div v-else>
      результаты
    </div>

    Чтобы показать вопрос, отрендерим экземпляр компонента вопроса, передав ему в качестве параметров содержимое элемента массива вопросов + привязав элемент массива ответов:

    <question
      v-bind="questions[index]"
      v-model="answers[index]"
    />

    Чтобы перейти к следующему вопросу, достаточно увеличить индекс текущего вопроса (кнопку, пока пользователь не выбрал ответ, можно: а) блокировать - :disabled="!answers[index]"; б) скрывать - v-show="answers[index]"):

    <button @click="index++">дальше</button>

    Результаты - список вопросов и соответствующих им (с тем же индексом) ответов:

    <div v-for="(n, i) in questions">
      {{ n.text }} - {{ answers[i] }}
    </div>


    https://jsfiddle.net/fdbj1w29/
    Ответ написан
    1 комментарий
  • Почему не обновляется state после успешного получения данных?

    0xD34F
    @0xD34F Куратор тега Vue.js
    return this.$store.authInfo

    А может, всё-таки this.$store.state.authInfo?
    Ответ написан
    4 комментария
  • Как не присваивать класс, если значение переменной null?

    0xD34F
    @0xD34F Куратор тега Vue.js
    :class="form.FirstName !== null ? form.FirstName ? 'input-successes' : 'input-error' : ''"

    или

    :class="{ 'input-successes': form.FirstName, 'input-error': form.FirstName === false }"

    или

    :class="form.FirstName !== null && [ 'input-error', 'input-successes' ][+form.FirstName]"

    или

    :class="({ true: 'input-successes', false: 'input-error' })[form.FirstName]"

    Лучше бы подобное конечно в computed/метод завернуть, как-то громоздко получается.
    Ответ написан
    2 комментария
  • Как вернуть копию значения с объекта в vuex store?

    0xD34F
    @0xD34F Куратор тега Vue.js
    после перезагрузки страницы получаю undefined

    Сохраняйте стейт в localStorage.

    Если лень реализовывать сохранение самостоятельно - есть готовые плагины, например.

    правильно ли я возвращаю копию значения с объекта store.singleMetricNamesMap

    Геттер в хранилище, возвращающий функцию, которая по переданному id возвращает объект... Не вижу, в чём смысл подобных сложностей.

    Просто читайте свойство объекта, типа $store.state.singleMetricNamesMap[value.metricId]. Если так по-вашему слишком длинно - сделайте в компоненте вычисляемое свойство, которое будет представлять singleMetricNamesMap.
    Ответ написан
    2 комментария
  • Как отобразить Яндекс карту в компоненте vue?

    0xD34F
    @0xD34F Куратор тега Яндекс.Карты
    Проблема из-за css. Для всех canvas'ов у вас задано правило width: 100% !important;, а родительский элемент canvas'а карты имеет нулевые размеры.

    UPD.

    new ymaps.Map("map", {

    Вот так делать не надо. Что если экземпляров компонента с картой будет больше одного? - двух, трёх и т.д. карт с одним id быть не может. Замените id на ref, и передавайте в конструктор карты вместо id сам элемент.
    Ответ написан
    3 комментария