Tree 组件在非 lazy load 的模式下,可以通过绑定 data 来实现修改数据时自动更新节点。但是开启了lazy load 模式时,如果仍绑定 data 或者使用 文档中 对传入函数中节点的 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 组件将结构和数据分离到了 Node
和 data
这两个概念中。如下图,Node
中有 childNodes
和 data
。Node
才是真正用来渲染视图中节点的,在非懒加载模式下,childNodes
中data
和 data
是一致关联的,也就是说 父节点data.push({...})
就会 新增一个 node
到 父节点的childNodes
,猜测 node
就是把 data
包裹了起来作为节点放在树型结构中。
但是在懒加载模式,文档中提到了
resolve
方法,稍微看下源码:
if (this.lazy && this.load) {
const loadFn = this.load;
loadFn(this.root, (data) => {
this.root.doCreateChildren(data);
this._initDefaultCheckedNodes();
});
}
恍然大悟,原来懒加载模式下需要手动 调用resolve
来把 node
加入到 childNodes
中,直接跳过修改data
,然后自动更新 childNodes
这一步。下面会用闭包来做一点点的hack,来实现 append
和remove
loadNode(node, resolve) { // 绑定给 load 属性
node.resolve = resolve;// 注意看这里
if (node.level === 0) { // 正要但没创建根节点时
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
})
});
},