Задать вопрос
@FriJ

Как отрисовывать нестандартные списки на Vue из API?

Прошу помощи в vue.js, а именно в директиве v-for. По API Я получаю похожую таблицу
5e835ac77189b651479279.png

Далее я пропускаю ее через v-for и получаю обычный список ul li, но мне нужно задать некую структуру.

Примерно такую:
5e835b3280e08831336161.png

Иными словами я бы хотел преобразовать все это в такой массив средствами JS или VUE и пропустить через v-for внутри друг друга
5e835b6c8a821015585037.png

Я новичок в создании REST API и хотелось бы узнать по стандартам:
1) Laravel должен вернуть JSON в преобразованном виде:
5e835b6c8a821015585037.png
или сыром, как тут:
5e835ac77189b651479279.png
?
2) Каким наиболее стандартизированным образом должна обрабатываться подобная структура?
3) И вообще, как правильно?
  • Вопрос задан
  • 171 просмотр
Подписаться 1 Средний Комментировать
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Vue.js
Надо сделать вычисляемое свойство, где плоский массив будет преобразовываться в подходящую структуру данных.

Если знаете заранее, как всё должно выглядеть, тогда можно сделать так, например:

computed: {
  groupedItems() {
    const { items } = this;
    const statuses = [...new Set(items.map(n => n.status))];
    const positions = [...new Set(items.map(n => n.position))];

    return items.reduce(
      (acc, n) => (acc[n.status][n.position].push(n), acc),
      Object.fromEntries(statuses.map(status => [
        status,
        Object.fromEntries(positions.map(position => [
          position,
          []
        ]))
      ]))
    );
  },
},

<ul>
  <li v-for="(statusGroup, status) in groupedItems">
    <h2>{{ status }}</h2>
    <ul>
      <li v-for="(positionGroup, position) in statusGroup">
        <h3>{{ position }}</h3>
        <ul>
          <li v-for="n in positionGroup">{{ n.name }}</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

В более общем случае для отображения данных понадобится рекурсивный компонент:

name: 'v-tree',
props: [ 'items' ],

<ul v-if="items instanceof Object">
  <li v-for="n in items">
    <b>{{ n.name }}</b>
    <v-tree :items="n.children" />
  </li>
</ul>

И функция группировки массива по произвольному количеству свойств:

const group = (arr, keys) =>
  arr.reduce((acc, n) => {
    keys.reduce((g, k, i, a) => {
      const name = n[k];
      return (g[name] = g[name] || {
        name,
        children: i === a.length - 1 ? [] : {},
      }).children;
    }, acc).push(n);

    return acc;
  }, keys.length ? {} : []);

Использоваться оно будет как-то так:

computed: {
  groupedItems() {
    return group(this.items, [ 'status', 'position' ]);
  },
},

<v-tree :items="groupedItems" />
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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