关于elementui tree组件修改节点数据无法更新视图
1.问题概述
在做项目的过程中用到elementui中的树组件,需求要做一个点击节点后显示选中的效果,如下图:
选中后显示图标,后端给的数据是没有是否选中的字段的,所以拿到数据后我先用递归给每一个节点添加selected属性默认值为false,在点击节点时进行判断 然后更改selected的值,选中图标用v-if根据selected显隐。
但是之后发现 点击节点后即便selected属性改变,选中图标并没有跟着更新。
2.问题分析
最初以为是组件的使用方式不太对,之后查阅文档发现是vue并不能很好的检测数组和对象的变化,详见vue文档:响应式检测变化注意事项.
因此,对于一些依赖数组或对象进行渲染的ui组件比如tree、table之类,在修改数组或对象内数据之后并不一定能及时响应进行视图更新。
3.解决方法
vue文档当中也提供了集中处理方法,但似乎并不使用我所遇到的状况。在分析原因之后得出结论如果使数据的变化可以被检测到,那么视图就会更新。
于是参照一些博客中的方法,我在改变数据selecte属性值之后对数据进行如下处理:
this.treeData=JSON.parse(JSON.stringify(this.treeData)
这样一来试图确实更新了,但显然这种方法有些粗陋,而且随之带来另一个问题,我们的数据并不只有两级,默认树只展开第一级,那点击第二级节点下的第三级节点后,因为总数据刷新,所以视图会直接重新更新到默认只展开第一级的状态。
接下来就使用了el-tree的方法,将被点击节点的父级找到,对父级数据进行更新,如下:
nodeClick(data, node) {
if (data.type == 1) {
return;
}
data.selected = data.selected ? false : true;
node.data = JSON.parse(JSON.stringify(node.data));
let idArr = [];
this.selectedList.forEach((item) => {
idArr.push(item.id);
});
let num = idArr.indexOf(data.id);
if (num > -1) {
this.selectedList.splice(num, 1);
} else {
this.selectedList.push({ id: data.id, name: data.name });
}
},
这样就只是对局部节点进行更新而不会重新更新整个视图了~
这只是权宜之计,虽然也可解决上述问题,但显然并不是完美方法,如果有更好的方法,欢迎分享~乐意求教