el-tree 踩过的坑 !!!
el-tree 相信前端的家人们都用过,最近维护公司的一个陈年老项目,遇到一个让我印象蛮深刻的 bug,是关于el-tree的,下面是我遇到的问题以及整个调试过程。
业务功能需求是这样的:要实现一个带复选框的树组件,并且该树组件带节点过滤功能,父子节点需要关联,也就是勾选父节点,该父节点下的子节点需要同步勾选,取消勾选亦是。乍一看好像没什么难的,于是乎打开 element-ui 官网,找到一个相似度高的示例<节点过滤>,直接代码 copy 过来,代码如下:
<template>
<div>
<el-input
placeholder="输入关键字进行过滤"
v-model="filterText">
</el-input>
<el-tree
class="filter-tree"
:data="data"
:props="defaultProps"
default-expand-all
:show-checkbox="true"
:filter-node-method="filterNode"
ref="tree">
</el-tree>
</div>
</template>
<script>
export default {
watch: {
filterText(val) {
this.$refs.tree.filter(val);
}
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
}
},
data() {
return {
filterText: '',
data: [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}, {
id: 110,
label: '三级 1-1-3'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
};
}
};
</script>
以上就得到了大致需要的功能,就差一个复选框,然后再加上 show-checkbox
属性和check
方法,以为这样就万事大吉了。但是自己测试的时候发现,好家伙,还藏了个bug
~是什么呢?
handleCheckChange(data, checked) {
console.log('handleCheckChange', data, checked);
},
handleCheck(data, isCheck) {
console.log('handleCheck', data, isCheck);
}
此时如果正常的进行勾一个选父节点(一级 1),然后控制台查看打印结果,如下:
单独测试节点过滤功能也是没有问题~~
最后一步测试问题来了,如果节点过滤后再进行勾选父节点呢,此时子节点会全部选中,相当于失去了节点过滤效果。 如在搜索框中输入“二级”,界面渲染的内容是没有什么问题,然后勾选一个父节点“一级 1”,此时控制台打印的结果却是出于意料。
我还以为是浏览器缓存的问题,或者是上次操作打印的结果,刷新刷新,重复上一步操作,再看控制台,打印的依旧是这样的结果,看来情况不大妙啊。此时再清空搜索框的内容,发现“一级 1”节点下的所有子节点确是全部选中的,果然不妙,是bug
找上门呀,嘤嘤嘤~,怎么会有bug
呢,什么鬼。
既然是节点的过滤,节点的data
数据又看不出有什么有用的地方,那么尝试从节点的node
数据下手呢?怎样获取到选中节点的node
呢?最后在官网寻到一个getNode
方法,根据data
或者 key
拿到 Tree
组件中的node
。
handleCheckChange(data, checked) {
let node = this.$refs.tree.getNode(data)
console.log('node', node)
}
将handleCheckChange
加上以上代码,然后同样的测试方法,搜索框输入二级
选中第一个父节点,观察控制台 node
的打印结果。
从打印结果来看,观察到有个visible
的属性,节点筛选后显示和未显示的节点该属性分别是 true
和false
,那么以此为突破口,可以通过该属性值去判断是否需要去手动改变node
的checked
属性值就好了。
handleCheckChange(data, checked) {
let node = this.$refs.tree.getNode(data)
console.log('node', node)
if(!node.visible) {
node.checked = false
}
}
搜索框清空后查看界面,任是想要的效果。到此终于解决了这个
bug
,暗自窃喜三秒钟。
以上就是我一个前端菜鸟关于el-tree
组件,遇到的一个不大不小的坑,以及笨拙的解bug
思路。整个调试流程都有截图,一(you)目(dian)了(luo)然(suo),希望对屏幕前的你有所帮助。如有你踩过的其它坑,或者关于以上有更好的解bug
思路和办法,或者关于以上有什么不明白的地方,欢迎评论区留言讨论哟~~~
转载自:https://juejin.cn/post/7044896128281608229