'Vuetify Tree-view --- Get parent node along with the children node
when I am trying to select a node in the Vuetify tree-view in leaf mode, I am getting only the leaf nodes in the v-model. Is there a way that I could get all the children node along with the selected parent node.
Vuetify Version: 2.2.18
Link to the code: https://codepen.io/pen/?&editable=true&editors=101
Result After selection:
Actual Result:
Child #1
Child #2
Grandchild #1
Grandchild #2
Expected Result:
Root
Child #1
Child #2
Child #3
Grandchild #1
Grandchild #2
Solution 1:[1]
The problem is that vuetify removes the parent nodes, as these contain all the child nodes. One solution is to build a computed flattened copy of the items that contains references to the parent nodes.
This can then be recursively looped through via a second computed property (_selection) which adds the parents of the selected items.
working example: https://codepen.io/ellisdod/pen/MWwqYBB?editors=1010
computed : {
_items () {
const replaceChildren = (obj,parent) => {
const clone = Object.assign({},obj)
delete clone.children
if (parent) clone.parent = parent
return clone
}
const addItems = (arr,parent) => {
const items = arr.reduce((acc,x)=>{
acc.push(replaceChildren(x,parent))
if (x.children) {
acc.push(addItems(x.children, x.id))
}
return acc
},[])
return items.flat()
}
return addItems(this.items).reduce((acc,x)=>{
acc[x.id]=x
return acc
},{})
},
_selection () {
const proxy = {}
addParents = (x, all) => {
const parentId = this._items[x.id].parent
if (parentId) {
if (all) addParents(this._items[parentId])
proxy[parentId] = this._items[parentId]
}
}
this.selection.forEach(x=>{
addParents(x,this.allParentNodes)
proxy[x.id] = x
})
return Object.values(proxy)
}
},
EDIT:
The recursion can be toggled with the allParentNodes property.
data : ()=> ({
allParentNodes : true,
})
Solution 2:[2]
TLDR: use selection-type="fix your god damn documentation"
I know that a moment has passed since this question was asked but I actually found out something interesting having the same problem
Turns out you can achieve desired result with a change in one line of code
You just have to specify selection-type as any string that isn't leaf or independent. Note that selection-type must not be omitted for desired result (it would otherwise default into leaf)
Personally I use fix your god damn documentation to relieve my frustration with said thing (info on described behaviouor is nowhere to be found in there)
Place that lead me to that solution: https://gitmemory.com/issue/vuetifyjs/vuetify/9088/543108633
Solution 3:[3]
I had the same problem and solved it by iterating over the internal nodes array of the treeview component, whenever the selection changes.
It seems the nodes array is a flattened version of the array containing an isSelected property along with the item.
In template:
<v-treeview
ref="tree"
v-model="selection"
...
></v-treeview>
In script:
data() {
return {
selection: [],
selectionWithParents: []
}
},
watch: {
selection() {
let _selectedNodes = []
let _treenodes = this.$refs['tree'].nodes
for (const key in _treenodes) {
if (Object.hasOwnProperty.call(_treenodes, key)) {
const node = _treenodes[key];
if (node.isSelected) _selectedNodes.push(node.item)
}
}
this.selectionWithParents = _selectedNodes;
}
}
Works fine in Vuetify v2.4.4.
Solution 4:[4]
const indexParent = this.data.findIndex(parent => parent.id == itemClicked.id_of_parent)
const indexChildren = this.data[indexParent].children.indexOf(indexChildren)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Ole Magnus Siqveland |
| Solution 4 | Julio Cesar |

