您好,登录后才能下订单哦!
在前端开发中,Element UI 是一个非常流行的 Vue.js 组件库,其中的 el-tree
组件常用于展示树形结构的数据。然而,在使用 el-tree
进行节点过滤时,可能会遇到一个问题:过滤后的节点不显示其下级节点。这个问题可能会影响用户体验,因此需要找到合适的解决方案。
本文将详细探讨 el-tree
节点过滤不显示下级问题的原因,并提供多种解决方案。我们将从基础概念入手,逐步深入,最终给出完整的代码示例和优化建议。
el-tree
组件简介el-tree
?el-tree
是 Element UI 提供的一个树形控件,用于展示层次结构的数据。它支持节点的展开、折叠、选中、拖拽等操作,非常适合用于文件目录、组织结构等场景。
el-tree
的基本用法<template>
<el-tree
:data="treeData"
:props="defaultProps"
@node-click="handleNodeClick"
></el-tree>
</template>
<script>
export default {
data() {
return {
treeData: [
{
label: '一级 1',
children: [
{
label: '二级 1-1',
children: [
{
label: '三级 1-1-1',
},
],
},
],
},
{
label: '一级 2',
children: [
{
label: '二级 2-1',
children: [
{
label: '三级 2-1-1',
},
],
},
{
label: '二级 2-2',
children: [
{
label: '三级 2-2-1',
},
],
},
],
},
],
defaultProps: {
children: 'children',
label: 'label',
},
};
},
methods: {
handleNodeClick(data) {
console.log(data);
},
},
};
</script>
el-tree
的过滤功能el-tree
提供了 filter-node-method
属性,用于自定义节点过滤的逻辑。通过这个属性,我们可以实现根据用户输入的关键词来过滤树节点。
<template>
<div>
<el-input v-model="filterText" placeholder="输入关键字进行过滤" />
<el-tree
:data="treeData"
:props="defaultProps"
:filter-node-method="filterNode"
ref="tree"
></el-tree>
</div>
</template>
<script>
export default {
data() {
return {
treeData: [
{
label: '一级 1',
children: [
{
label: '二级 1-1',
children: [
{
label: '三级 1-1-1',
},
],
},
],
},
{
label: '一级 2',
children: [
{
label: '二级 2-1',
children: [
{
label: '三级 2-1-1',
},
],
},
{
label: '二级 2-2',
children: [
{
label: '三级 2-2-1',
},
],
},
],
},
],
defaultProps: {
children: 'children',
label: 'label',
},
filterText: '',
};
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
},
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
},
};
</script>
在使用 el-tree
进行节点过滤时,可能会遇到一个问题:过滤后的节点不显示其下级节点。例如,当用户输入“二级”进行过滤时,只有“二级”节点会被显示,而其下级节点(如“三级 1-1-1”)则不会被显示。
<template>
<div>
<el-input v-model="filterText" placeholder="输入关键字进行过滤" />
<el-tree
:data="treeData"
:props="defaultProps"
:filter-node-method="filterNode"
ref="tree"
></el-tree>
</div>
</template>
<script>
export default {
data() {
return {
treeData: [
{
label: '一级 1',
children: [
{
label: '二级 1-1',
children: [
{
label: '三级 1-1-1',
},
],
},
],
},
{
label: '一级 2',
children: [
{
label: '二级 2-1',
children: [
{
label: '三级 2-1-1',
},
],
},
{
label: '二级 2-2',
children: [
{
label: '三级 2-2-1',
},
],
},
],
},
],
defaultProps: {
children: 'children',
label: 'label',
},
filterText: '',
};
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
},
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
},
};
</script>
在上述代码中,当用户输入“二级”进行过滤时,只有“二级”节点会被显示,而其下级节点(如“三级 1-1-1”)则不会被显示。
这个问题的根本原因在于 el-tree
的过滤逻辑。默认情况下,el-tree
只会显示匹配过滤条件的节点,而不会显示其下级节点。即使下级节点本身也匹配过滤条件,也不会被显示。
我们可以通过递归的方式,在过滤时不仅检查当前节点是否匹配过滤条件,还要检查其下级节点是否匹配。如果下级节点匹配,则将其上级节点也显示出来。
<template>
<div>
<el-input v-model="filterText" placeholder="输入关键字进行过滤" />
<el-tree
:data="filteredTreeData"
:props="defaultProps"
ref="tree"
></el-tree>
</div>
</template>
<script>
export default {
data() {
return {
treeData: [
{
label: '一级 1',
children: [
{
label: '二级 1-1',
children: [
{
label: '三级 1-1-1',
},
],
},
],
},
{
label: '一级 2',
children: [
{
label: '二级 2-1',
children: [
{
label: '三级 2-1-1',
},
],
},
{
label: '二级 2-2',
children: [
{
label: '三级 2-2-1',
},
],
},
],
},
],
defaultProps: {
children: 'children',
label: 'label',
},
filterText: '',
};
},
computed: {
filteredTreeData() {
return this.filterTree(this.treeData, this.filterText);
},
},
methods: {
filterTree(treeData, filterText) {
return treeData.filter(node => {
if (node.children) {
node.children = this.filterTree(node.children, filterText);
}
return (
node.label.indexOf(filterText) !== -1 ||
(node.children && node.children.length > 0)
);
});
},
},
};
</script>
filter-node-method
自定义过滤逻辑我们可以在 filter-node-method
中自定义过滤逻辑,确保在过滤时不仅检查当前节点,还要检查其下级节点。
<template>
<div>
<el-input v-model="filterText" placeholder="输入关键字进行过滤" />
<el-tree
:data="treeData"
:props="defaultProps"
:filter-node-method="filterNode"
ref="tree"
></el-tree>
</div>
</template>
<script>
export default {
data() {
return {
treeData: [
{
label: '一级 1',
children: [
{
label: '二级 1-1',
children: [
{
label: '三级 1-1-1',
},
],
},
],
},
{
label: '一级 2',
children: [
{
label: '二级 2-1',
children: [
{
label: '三级 2-1-1',
},
],
},
{
label: '二级 2-2',
children: [
{
label: '三级 2-2-1',
},
],
},
],
},
],
defaultProps: {
children: 'children',
label: 'label',
},
filterText: '',
};
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
},
},
methods: {
filterNode(value, data, node) {
if (!value) return true;
const contains = data.label.indexOf(value) !== -1;
if (contains) return true;
if (node.childNodes) {
return node.childNodes.some(child => this.filterNode(value, child.data, child));
}
return false;
},
},
};
</script>
expand-on-click-node
属性我们可以通过设置 expand-on-click-node
属性为 false
,来防止节点在点击时自动展开。这样,用户需要手动展开节点,从而避免过滤后下级节点不显示的问题。
<template>
<div>
<el-input v-model="filterText" placeholder="输入关键字进行过滤" />
<el-tree
:data="treeData"
:props="defaultProps"
:filter-node-method="filterNode"
:expand-on-click-node="false"
ref="tree"
></el-tree>
</div>
</template>
<script>
export default {
data() {
return {
treeData: [
{
label: '一级 1',
children: [
{
label: '二级 1-1',
children: [
{
label: '三级 1-1-1',
},
],
},
],
},
{
label: '一级 2',
children: [
{
label: '二级 2-1',
children: [
{
label: '三级 2-1-1',
},
],
},
{
label: '二级 2-2',
children: [
{
label: '三级 2-2-1',
},
],
},
],
},
],
defaultProps: {
children: 'children',
label: 'label',
},
filterText: '',
};
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
},
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
},
};
</script>
default-expand-all
属性我们可以通过设置 default-expand-all
属性为 true
,来默认展开所有节点。这样,即使过滤后下级节点也会被显示。
<template>
<div>
<el-input v-model="filterText" placeholder="输入关键字进行过滤" />
<el-tree
:data="treeData"
:props="defaultProps"
:filter-node-method="filterNode"
:default-expand-all="true"
ref="tree"
></el-tree>
</div>
</template>
<script>
export default {
data() {
return {
treeData: [
{
label: '一级 1',
children: [
{
label: '二级 1-1',
children: [
{
label: '三级 1-1-1',
},
],
},
],
},
{
label: '一级 2',
children: [
{
label: '二级 2-1',
children: [
{
label: '三级 2-1-1',
},
],
},
{
label: '二级 2-2',
children: [
{
label: '三级 2-2-1',
},
],
},
],
},
],
defaultProps: {
children: 'children',
label: 'label',
},
filterText: '',
};
},
watch: {
filterText(val) {
this.$refs.tree.filter(val);
},
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
},
};
</script>
在处理大量数据时,递归过滤可能会导致性能问题。为了提高性能,可以考虑以下优化措施:
el-tree
节点过滤不显示下级节点的问题,主要是由于默认的过滤逻辑只检查当前节点是否匹配过滤条件。通过递归过滤、自定义过滤逻辑、设置 expand-on-click-node
或 default-expand-all
属性,我们可以有效地解决这个问题。
在实际开发中,我们需要根据具体需求选择合适的解决方案,并结合性能优化和用户体验优化,提供更好的用户界面。
以下是完整的参考代码,结合了递归过滤和自定义过滤逻辑:
<template>
<div>
<el-input v-model="filterText" placeholder="输入关键字进行过滤" />
<el-tree
:data="filteredTreeData"
:props="defaultProps"
ref="tree"
></el-tree>
</div>
</template>
<script>
export default {
data() {
return {
treeData: [
{
label: '一级 1',
children: [
{
label: '二级 1-1',
children: [
{
label: '三级 1-1-1',
},
],
},
],
},
{
label: '一级 2',
children: [
{
label: '二级 2-1',
children: [
{
label: '三级 2-1-1',
},
],
},
{
label: '二级 2-2',
children: [
{
label: '三级 2-2-1',
},
],
},
],
},
],
defaultProps: {
children: 'children',
label: 'label',
},
filterText: '',
};
},
computed: {
filteredTreeData() {
return this.filterTree(this.treeData, this.filterText);
},
},
methods: {
filterTree(treeData, filterText) {
return treeData.filter(node => {
if (node.children) {
node.children = this.filterTree(node.children, filterText);
}
return (
node.label.indexOf(filterText) !== -1 ||
(node.children && node.children.length > 0)
);
});
},
},
};
</script>
通过以上代码,我们可以实现 el-tree
节点过滤时显示下级节点的功能,从而提升用户体验。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。