@outcome

Как реализовать связанные select'ы?

Хочу реализовать возможность использования связанных списков в Vuetify на основе v-select. Идея в том, что есть иерархический объект с данными, каждый дочерний элемент которого отображается в следующем селекторе.

Вот пример этого объекта
items: [
    {
        title: 'A',
        value: 1,
        //
        childs: [
            {
                title: 'A-A',
                value: 11,
                //
                childs: [
                    {
                        title: 'A-A-A',
                        value: 111,
                    },
                ],
            },
        ],
    },
    {
        title: 'B',
        value: 2,
        //
        childs: [
            {
                title: 'B-B #1',
                value: 21,
            },
            {
                title: 'B-B #2',
                value: 22,
            },
        ],
    },
],

Вот тут практически полностью рабочий пример: https://codepen.io/NeverAgain/pen/jOZpQVp

На верхнем уровне у нас есть данные для первого селектора — A, B, C. У каждого из них есть дочерний объект CHILDS, который содержит аналогичную структуру данных для последующих селекторов в форме.

При выборе одного из вариантов (A, B, C) в первом селекторе, во втором сразу будет отображаться то, что содержится в соответствующем CHILDS. Но если в родительском селекторе изменить выбор, вся цепочка последующих селекторов сбросится, кроме значений переменных, на которые указывают их v-model.

И вот это как раз и является основной проблемой.

Знаю, что для VueJS есть библиотека по работе с селекторами, но во-первых - хочется узнать, как исправить мой код, чтобы он выполнял то, что положено, во-вторых - т.к. недавно работаю со связкой VueJS+Vuetify - не знаю, как с вьютифаем подружится либа, созданная чисто для вью.
  • Вопрос задан
  • 287 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Vue.js
Выбранные значения:

data: () => ({
  selected: [ null, null, null ],
  ...
}),

Получение массивов данных для селектов:

computed: {
  selectData() {
    const data = Array.from({ length: this.selected.length }, () => []);

    for (let { items } = this.selectors, i = 0; items && i < data.length; i++) {
      data[i] = items;
      items = items.find(n => n.value === this.selected[i])?.childs;
    }

    return data;
  },
  ...
},

Сброс выбранных значений:

methods: {
  resetSelected(index) {
    for (let i = index; i < this.selected.length; i++) {
      this.selected[i] = null;
    }
  },
  ...
},

Собираем всё вместе:

<v-col v-for="(n, i) in selected" cols="4">
  <v-select
    :items="selectData[i]"
    item-text="title"
    item-value="value"
    v-model="selected[i]"
    @change="resetSelected(i + 1)"
  ></v-select>
</v-col>
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы