Reputation: 421
I'm currently making a tree view using Vuetify. The tree view uses this structure:
items: [
{
id: 1,
name: 'Applications :',
children: [
{ id: 2, name: 'Calendar : app' },
{ id: 3, name: 'Chrome : app' },
{ id: 4, name: 'Webstorm : app' }
]
},
{
id: 5,
name: 'Documents :',
children: [
{
id: 6,
name: 'vuetify :',
children: [
{
id: 7,
name: 'src :',
children: [
{ id: 8, name: 'index : ts' },
{ id: 9, name: 'bootstrap : ts' }
]
}
]
},
{
id: 10,
name: 'material2 :',
children: [
{
id: 11,
name: 'src :',
children: [
{ id: 12, name: 'v-btn : ts' },
{ id: 13, name: 'v-card : ts' },
{ id: 14, name: 'v-window : ts' }
]
}
]
}
]
},
{
id: 15,
name: 'Downloads :',
children: [
{ id: 16, name: 'October : pdf' },
{ id: 17, name: 'November : pdf' },
{ id: 18, name: 'Tutorial : html' }
]
},
{
id: 19,
name: 'Videos :',
children: [
{
id: 20,
name: 'Tutorials :',
children: [
{ id: 21, name: 'Basic layouts : mp4' },
{ id: 22, name: 'Advanced techniques : mp4' },
{ id: 23, name: 'All about app : dir' }
]
},
{ id: 24, name: 'Intro : mov' },
{ id: 25, name: 'Conference introduction : avi' }
]
}
]
})
And it will look like this:
My problem is in adding a new node to this structure, For example if I want to add a child under applications then the code would probably look like this:
this.items[0].children.push(newObject)
Or if I want to add under src? then it might look like this:
this.items[1].children[0].children.push(newObject)
If I want to go deeper then it might look like this:
this.items[0].children[0].children[0].children[0].children[0].children.push(newObject)
As you can see, the way I add a node varies and the code changes depending on the location and depth of where I want to add the node. That means there is no single code that will cater for all the locations. Also I can add and nest as many node as I can. example is google drive How should I go about this? I've run out of ideas and is looking for any suggestions that might help.
Upvotes: 4
Views: 8213
Reputation: 20745
If you are adding nodes directly from the tree, the easiest way is by using scoped slots. For example, you can use the append
slot to add something to each item. Since the item is passed to the slot, you can pass it to a function that can easily add a child to that object.
<v-app>
<v-treeview :items="items">
<template slot="append" slot-scope="{ item }">
<v-btn @click="addChild(item);">Add child</v-btn>
</template>
</v-treeview>
</v-app>
addChild(item) {
if (!item.children) {
this.$set(item, "children", []);
}
const name = `${item.name} (${item.children.length})`;
const id = this.nextId++;
item.children.push({
id,
name
});
}
Otherwise just walk recursively through the tree until you find the item you want to add to.
findItem(id, items = null) {
if (!items) {
items = this.items;
}
return items.reduce((acc, item) => {
if (acc) {
return acc;
}
if (item.id === id) {
return item;
}
if (item.children) {
return this.findItem(id, item.children);
}
return acc;
}, null);
}
You can see an example in codesandbox.
Upvotes: 7