I have an object like this:
[
{"id":1,"parentId":null,"name":"Parent1"},
{"id":2,"parentId":null,"name":"Parent2"},
{"id":3,"parentId":null,"name":"Parent3"},
{"id":4,"parentId":1,"name":"Child1Parent1"},
{"id":5,"parentId":1,"name":"Child2Parent1"},
{"id":6,"parentId":2,"name":"Child1Parent2"},
{"id":7,"parentId":null,"name":"Parent4"}
... ]
I have to return grouped Array by Id and ParentId in table with expanded childs if exist like:
[
{
{"id":4,"parentId":1,"name":"Child1Parent1"},
{"id":5,"parentId":1,"name":"Child2Parent1"}
},
{
{"id":6,"parentId":2,"name":"Child1Parent2"}
},
{"id":3,"parentId":null,"name":"Parent3"},
... ]
I took the liberty to take @procoib's answer a bit further and I added a few more details to to it, allowing the markup to be more expressive:
Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
el: '#app',
data: () => ({
items: [
{ "id": 1, "parentId": null, "name": "Parent1" },
{ "id": 2, "parentId": null, "name": "Parent2" },
{ "id": 3, "parentId": null, "name": "Parent3" },
{ "id": 4, "parentId": 1, "name": "Child1Parent1" },
{ "id": 5, "parentId": 1, "name": "Child2Parent1" },
{ "id": 6, "parentId": 2, "name": "Child1Parent2" },
{ "id": 7, "parentId": null, "name": "Parent4" }
].map(i => ({ ...i,
expanded: true
}))
}),
computed: {
parents() {
return this.items.filter(g => !g.parentId)
},
children() {
return this.items.filter(g => g.parentId)
}
},
methods: {
childrenOf(id) {
return this.items.filter(g => g.parentId === id)
}
}
})
.cursor-pointer {
cursor: pointer;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<div id="app">
<table class="table table-sm">
<thead>
<tr>
<th>ID</th>
<th>parentId</th>
<th>name</th>
</tr>
</thead>
<tbody>
<template v-for="parent in parents">
<tr>
<th colspan="3"
class="bg-light">
{{parent.name}}
<code v-if="childrenOf(parent.id).length"
class="font-weight-light cursor-pointer"
@click="parent.expanded = !parent.expanded">[{{
parent.expanded ? 'hide' : 'show'
}}]</code>
</th>
</tr>
<tr v-for="child in childrenOf(parent.id)" v-show="parent.expanded">
<td v-text="child.id" />
<td v-text="child.parentId"/>
<td v-text="child.name"/>
</tr>
</template>
</tbody>
</table>
</div>