vue 实战技巧之 el-tree 使用技巧
本次讲述的是关于 el-tree
1 与 el-input
2 组合而实现的: 树状结构 查询树子节点的功能。
树状结构查询子节点的共功能分为如下几点:
- 查询单层的子节点的节点信息
- 查询多层子节点的节点信息(即查询子节点所包含的所有节点)
有时候对一个树状结构的数据进行查询时,只需要查询到其中某一级的数据就可以了,比如菜单权限树结构选择。
有时候对一个树状结构的数据进行查询时,除了要查询出某一级的节点数据,还要把这一节点的所有子节点全部显示出来,比如在查询某一个电厂的设备时,查询到某一个电厂就需要将这个电厂下的所有设备全部查询出来,而不是仅查出来电厂,完全看不到电厂下的设备导致用户无法选择设备。
下面进行详细的功能说明和功能的实现。
el-tree
组件渲染部分的结构如下所示:
<div class="aside-tree-inner">
<el-input
v-model="searchValue"
clearable
suffix-icon="el-icon-search"
@input="handleSearch"
></el-input>
<el-tree
ref="tree"
node-key="id"
:data="treeData"
:filter-node-method="handleFilterNodeMethod"
></el-tree>
</div>
el-tree
组件所需要的数据格式如下所示:
注意:treeData
数据中有一个 id
和 parentId
这两个字段是非常重要的,id
是 el-tree
组件所需要的 key
值,用来标识节点的唯一性,至于 parentId
会在【过滤 el-tree 节点,保留子节点数据】时用到,后面会说到。
export default {
data() {
this.searchParentIdList = []
return {
searchValue: '',
treeData: [
{ id: '01', parentId: '0', label: '南京市',
children: [
{ id: '0101', parentId: '01', label: 'Node A',
children: [
{ id: '010101', parentId: '0101', label: 'Node 1' },
{ id: '010102', parentId: '0101', label: 'Node 2' },
{ id: '010103', parentId: '0101', label: 'Node 3' },
]
},
{ id: '0102', parentId: '01', label: 'Node B',
children: [
{ id: '010201', parentId: '0102', label: 'Node 4' },
{ id: '010202', parentId: '0102', label: 'Node 5' },
{ id: '010203', parentId: '0102', label: 'Node 6' },
]
}
]
},
{ id: '02', parentId: '0', label: '南通市',
children: [
{ id: '0201', parentId: '02', label: 'Node C' },
{ id: '0202', parentId: '02', label: 'Node D' }
]
},
{ id: '03', parentId: '0', label: '镇江市',
children: [
{ id: '0301', parentId: '03', label: 'Node E' },
{ id: '0302', parentId: '03', label: 'Node F' }
]
},
{ id: '04', parentId: '0', label: '徐州市',
children: [
{ id: '0401', parentId: '04', label: 'Node G' },
{ id: '0402', parentId: '04', label: 'Node H' }
]
}
]
}
},
methods: {}
}
过滤 el-tree 节点,查询某一个节点的数据
模糊查询某一个层级的某一个节点,不会显示这个层级的所有子节点数据。
注意:在 el-tree
数据中有一个 id
字段比较重要,因为这个 id
是用来标识节点数据的唯一性的,方便进行对节点进行查找,类似于给每个节点做了一个索引。
export default {
data() {
return {...}
},
methods: {
// 查询条件
handleSearch() {
this.$refs.tree.filter(this.searchValue)
},
// 过滤方法
handleFilterNodeMethod(value, node) {
if (!value) return true
return node.label.indexOf(value) > -1
}
}
}
handleSearch
为搜索框查询条件的监听事件,此处使用的监听事件是@input
,可以做到在输入的同时及时反馈查询的结果;可以使用@keyup.enter
事件,在用户触发回车键的时候查询结果。this.$refs.tree.filter
是el-tree
组件提供的一个方法,用于对节点过滤,调用的同时会触发filter-node-method
属性的状态变化。handleFilterNodeMethod
为组件的过滤方法,是通过node
节点的字段值进行比较来确定当前节点是否显示,如果是则返回true
,否则返回false
。
过滤 el-tree 节点,查询某一个节点并带出这个节点所有的子节点数据
这里有两个字段非常重要 id
和 parentId
, id
使用来标识节点的唯一性的,parentId
是有用来关联子节点与父节点之间的关系的。
通过上面 【过滤 el-tree 节点,仅保留当前层级的节点数据】的介绍,我们可以知道,简单的使用 id
是无法做到在查询到父节点时带出父节点下所有的子节点数据的,所以在我们查询到某一个节点时,首先要判断当前节点是否还有下一级的节点,如果有,则对下一个层级的节点进行递归遍历查出所有的子节点。
我们需要先定义一个存储器(或者叫空数组),用来存放那些需要显示的节点 id
, 比如在 当前实例对象声明一个存储器 this.searchParentIdList = []
,然后我们在查询某一个节点的时候,先查询一下当前节点是否已经存在于存储器中了,如果已经存在,则只需将该节点显示出来即可,然后再查找当前节点是否存在下一级,如果存在,则继续向下查找,直到最后以及,并把当前节点下一级的所有节点id
存储再存储器中。
export default {
data() {
return {...}
},
methods: {
// 查询条件
handleSearch() {
this.searchParentIdList = []
this.$refs.tree.filter(this.searchValue)
},
// 过滤方法
handleFilterNodeMethod(value, node) {
if (!value) return true
if (this.searchParentIdList.includes(node.parentId)) return true
if (node.label.indexOf(value) > -1) {
this.getNodeId(node)
return true
}
return false
},
// 获取子节点的ID
getNodeId(node) {
this.searchParentIdList.push(node.id)
if (node.children && node.children.length > 0) {
node.children.forEach(v => this.getNodeId(v))
}
}
}
}
- getNodeId 方法使用来递归查询每个节点的id,并把需要显示在界面中的id存储在存储器中。