Tree 組件在非 lazy load 的模式下,可以通過綁定 data 來實現(xiàn)修改數(shù)據(jù)時自動更新節(jié)點。但是開啟了lazy load 模式時,如果仍綁定 data 或者使用 文檔中 對傳入函數(shù)中節(jié)點的 data 的修改是不會刷新視圖的。下面貼出文檔的代碼(不起作用)。
append(data) {
const newChild = { id: id++, label: 'testtest', children: [] };
if (!data.children) {
this.$set(data, 'children', []);
}
data.children.push(newChild); // lazy load 模式下不會刷新視圖
},
remove(node, data) {
const parent = node.parent;
const children = parent.data.children || parent.data;
const index = children.findIndex(d => d.id === data.id);
children.splice(index, 1); // lazy load 模式下不會刷新視圖
},
由文檔知,Tree 組件將結(jié)構(gòu)和數(shù)據(jù)分離到了 Node和 data這兩個概念中。如下圖,Node中有 childNodes 和 data 。Node 才是真正用來渲染視圖中節(jié)點的,在非懶加載模式下,childNodes中data和 data是一致關(guān)聯(lián)的,也就是說 父節(jié)點data.push({...}) 就會 新增一個 node到 父節(jié)點的childNodes,猜測 node 就是把 data 包裹了起來作為節(jié)點放在樹型結(jié)構(gòu)中。

node中的數(shù)據(jù)
但是在懶加載模式,文檔中提到了
resolve 方法,稍微看下源碼:
if (this.lazy && this.load) {
const loadFn = this.load;
loadFn(this.root, (data) => {
this.root.doCreateChildren(data);
this._initDefaultCheckedNodes();
});
}
恍然大悟,原來懶加載模式下需要手動 調(diào)用resolve 來把 node 加入到 childNodes中,直接跳過修改data,然后自動更新 childNodes這一步。下面會用閉包來做一點點的hack,來實現(xiàn) append和remove
loadNode(node, resolve) { // 綁定給 load 屬性
node.resolve = resolve;// 注意看這里
if (node.level === 0) { // 正要但沒創(chuàng)建根節(jié)點時
node.resolve = resolve; // 注意看這里
return resolve(this.treeData);
}
this.$axios.get(`/orgs/${node.data.id}/orgs`).then(res => {
return resolve(res.data);
});
},
appendTreeNode(node,data) {
this.$axios.post('/orgs', {
name: '',
superOrgId: data.id
}).then(res => {
let children = [];
children.push(res.data);
node.childNodes.forEach(d=>children.push(d.data));
node.resolve(children);
});
},
removeTreeNode(node, data) {
let parent = node.parent;
let children = parent.childNodes;
const index = children.findIndex(d => d.data.id === data.id);
children.splice(index, 1);
this.$axios.delete(`/orgs/${data.id}`).then(()=>{
this.$message({
message:'已刪除',
showClose:true
})
});
},