Задать вопрос
Контакты
Местоположение
Россия, Москва и Московская обл., Москва

Достижения

Все достижения (212)

Наибольший вклад в теги

Все теги (145)

Лучшие ответы пользователя

Все ответы (5885)
  • Как управлять состоянием множества диалоговых окон (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 комментарий
  • Как сделать фильтрацию по нескольким значениям в VueJS?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сложно это всё. Четыре селекта - очень похожие, четыре вычисляемых свойства - очень похожие. Многовато копипасты. Надо упростить.

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

    filters: [
      { name: 'calculator.brand_filter', getter: obj => obj.brand.name, value: '' },
      { name: 'calculator.company_filter', getter: obj => obj.company.name, value: '' },
      { name: 'calculator.country_filter', getter: obj => obj.brand.country, value: '' },
      { name: 'calculator.side_filter', getter: obj => obj.sides, value: '' },
    ],

    Затем сделаем собственно фильтрацию, пропустим данные через массив фильтров (если значение фильтра выставлено - производится фильтрация, нет - оставляем данные как есть):

    computed: {
      filteredProfiles() {
        return this.filters.reduce((profiles, { value, getter }) => {
          return value
            ? profiles.filter(n => getter(n) === value)
            : profiles;
        }, this.profiles);
      },

    Далее, надо дать пользователю возможность задавать значения фильтров. Сделаем компонент фильтра:

    Vue.component('filter-select', {
      props: [ 'name', 'options', 'value' ],
      template: `
    <div>
      <p>{{ name }}<p>
      <select :value="value" @change="$emit('input', $event.target.value)">
        <option value="">-</option>
        <option v-for="n in options">{{ n }}</option>
      </select>
    </div>`
    });

    Подготовим опции для фильтров - массивы уникальных значений, по которым будет осуществляться фильтрация:

    computed: {
      filterOptions() {
        return this.filters.map(n => [...new Set(this.profiles.map(n.getter))]);
      },

    Наконец, создадим сами фильтры:

    <filter-select
      v-for="(n, i) in filters"
      v-model="n.value"
      :options="filterOptions[i]"
      :name="trans(n.name)"
    ></filter-select>

    Также не будем забывать про обнуление значений фильтров. Так что вот метод сброса фильтров и кнопка, по клику на которую он будет вызываться:

    methods: {
      resetFilters() {
        this.filters.forEach(n => n.value = '');
      },

    <button @click="resetFilters">{{ trans('calculator.reset_filter') }}</button>

    Демо можно посмотреть здесь (да, тут меньше фильтров, чем у вас - ну так вы свои данные не показали, а у меня воображения на большее не хватило).
    Ответ написан
    1 комментарий
  • Как рендерить слоты в списке?

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

    Но если всё-таки нужно использовать именно слот - пишите собственную render-функцию. Т.е., вместо шаблона, который есть у вас сейчас, будет что-то вроде

    export default {
      render(h) {
        return h('ul', this.$slots['list-item'].map(n => h('li', [ n ])));
      },
    };


    UPD. Если, помимо собственно списка в будущем планируется добавить в компонент List ещё какие-то элементы, то наверное будет не очень удобно рендерить всё это дело через функцию, поэтому можно написать небольшой компонент-обёртку для элементов слота:

    components: {
      SlotWrapper: {
        functional: true,
        render: (h, context) => context.props.node,
      },
    },

    <li v-for="n in $slots['list-item']">
      <slot-wrapper :node="n"></slot-wrapper>
    </li>
    Ответ написан
    5 комментариев
  • Как реализовать подзагрузку страницы перед переходом на нее в Vue JS?

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

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

    0xD34F
    @0xD34F Куратор тега Vue.js
    Поиск по свойствам вложенных объектов "из коробки" не предусмотрен. Так что без костылей не обойтись.

    Вижу три варианта:
    • Перенос свойств вложенных объектов непосредственно в объект строки таблицы. То есть, сейчас у вас есть { user: { city: { name: "..." } } } , а будет { userCityName: "..." } или { user_city_name: "..." }, как-то так.
    • Создание кастомных фильтров по столбцам, созданным с помощью templates. Всё вручную - создание фильтра, написание логики его работы и т.д. Также из минусов данного подхода - элементы управления кастомных фильтров находятся за пределами таблицы, в отличие от встроенных. Нагуглил пример реализации, на его основе сделал пример поиска по свойствам вложенных объектов.
    • Наконец, можно обернуть данные в Proxy. Определять templates в этом случае не нужно, всё работает так, будто интересующие нас свойства принадлежат не вложенным объектам, а непосредственно объекту строки таблицы. Соответственно, и встроенный поиск тоже доступен. Идея в чем: делаем get-ловушку, в ней режем имя свойства, например "user.city.name", на куски, идём вглубь по полученной цепочке имён, достаём значение. Опять же, сделал небольшой пример.

    UPD. Добавили возможность определять методы фильтрации для отдельных столбцов, так что вот четвёртый вариант.
    Ответ написан
    Комментировать