Надо сделать вычисляемое свойство, где плоский массив будет преобразовываться в подходящую структуру данных.
Если знаете заранее, как всё должно выглядеть, тогда можно сделать
так, например:
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" />