预览
前言
在使用 Element UI 的 el-tree 组件进行关键字过滤时,默认行为是:只展示匹配的节点本身,但其子节点不会被保留显示。这在实际业务中,可能会带来一些使用体验上的问题。例如,当一个父节点匹配关键字时,我们希望它的所有子节点也能一并展示出来,方便查看和操作。
本文将通过一个具体的示例,实现“el-tree 保持搜索目标子节点展示”的功能,并与 Element UI 默认的查询方式做对比。
实现思路
主要逻辑分为三部分:
- 通过
filterNode函数自定义过滤规则; - 如果一个节点匹配关键字,则递归调用函数
filter(),将其所有子节点设置为可见; - 使用
$refs.tree.getNode(data)获取节点实例,并手动设置visible = true。
<template>
<div>
<el-input
placeholder="输入关键字进行过滤"
v-model="filterText">
</el-input>
<div style="display: flex;justify-content: space-around">
<div>
<p style="color: red">修改后的查询</p>
<el-tree :data="data1"
default-expand-all
:filter-node-method="filterNode"
ref="tree">
</el-tree>
</div>
<div>
<p style="color: red">element-ui 提供的查询</p>
<el-tree :data="data1"
default-expand-all
:filter-node-method="filterNode1"
ref="tree1">
</el-tree>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
filterText: '',
data1: [{
id: 100,
label: '1263',
children: [
{
id: 100,
label: '852',
}, {
id: 111,
label: '369',
}, {
id: 852,
label: 'ki',
children: [
{
id: 96,
label: 'pp',
}
]
},
]
}, {
id: 1,
label: '一级 1',
children: [{
id: 4,
label: 'gf',
children: [{
id: 23,
label: 'lk',
children: [
{
id: 9,
label: 'abnc'
}, {
id: 11,
label: 'abnc43'
}, {
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: 56,
label: 'test',
children: [
{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}
]
}]
}],
}
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
this.$refs.tree1.filter(val);
}
},
methods: {
/**
* 遍历节点
**/
filterNode(value, data) {
if (data.label.indexOf(value) !== -1) {
if (data.children && data.children.length) {
this.$nextTick(() => {
data.children.forEach((item) => {
this.filter(item)
})
})
}
return true
}
},
filterNode1(value, data) {
if (data.label.indexOf(value) !== -1) {
return true
}
},
/**
* 递归遍历设置子节点保持展示
**/
filter(data) {
const node = this.$refs.tree.getNode(data)
node.visible = true
if (data.children && data.children.length) {
data.children.forEach((item) => {
this.filter(item)
})
}
}
},
}
</script>