最近树形结构的东西整的有点多,也遇到一些小问题,关于el-tree过滤节点,官方给出的例子挺不错的,但是结合实际需求又有些出入,所以自己又花了点时间调试
首先讲讲需求:
竖行结构列表上选中某个节点的编辑功能,可以修改他的父级节点,即可以将该节点以及子节点一起更改挂载的父节点
这就需要过滤功能去将选中节点以及选中节点的子节点全部都过滤掉,避免选到自己的子节点死循环
- 我们先来看看官网的例子
//官网例子
<el-input
placeholder="输入关键字进行过滤"
v-model="filterText">
</el-input>
<el-tree
class="filter-tree"
:data="data2"
:props="defaultProps"
default-expand-all
:filter-node-method="filterNode"
ref="tree2">
</el-tree>
<script>
export default {
watch: {
filterText(val) {
this.$refs.tree2.filter(val);
}
},
methods: {
//不会返回匹配的node的子节点
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
}
},
data() {
return {
filterText: '',
data2: [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
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>
- 一开始我就犯了个逻辑问题,我想当然的以为过滤掉当前节点就自然会把子节点过滤掉,然而实际情况还是没有过滤掉子节点,当前节点都不会被过滤掉,除非当前就没有子节点,才能过滤自己这一个节点,
好吧那就先递归(写的很直白 有需要也可以用es6简化):
//递归遍历所有 id
getChildIds(arr,id){
var childIds=[]
function a(arr){
for(var i=0;i<arr.length;i++){
if(id===arr[i].id){
childIds.push(arr[i].id)
if(arr[i].children){
b(arr[i].children)
}
}else{
if(arr[i].children){
a(arr[i].children)
}
}
}
}
function b(arr){
for(var i=0;i<arr.length;i++){
childIds.push(arr[i].id)
if(arr[i].children){
b(arr[i].children)
}
}
}
a(arr)
return childIds
}
3.这个时候就获取了当前节点以及他子节点的所有id数组,
然后就用过滤方法过滤了,当时也是写了个错误的map遍历,算了 直接给正确答案
//首先
this.$refs.tree2.filter(this.childIds);
//过滤
filterNode(value,data){
return value.indexOf(data.id) === -1;
}
然后就完成需求了,不过作者本身也遇到一个问题,就是过滤后,树形结构会默认展开状态,不清楚是不是因为全部过滤 一次的原因,如果有小伙伴知道原因,能改为不展开,评论告诉我一下,谢谢。