一、前言
今天来写一篇这样的文章,主要解决el-tree在大量数据下的卡顿问题,同时还包含了一些其它的逻辑处理,主要包括:
- 10W+节点虚拟滚动,解决浏览器卡顿问题
- 创建顶级节点、创建子节点,及创建后的自动展开和创建节点高亮问题的处理
- 自定义节点内容,点击节点操作阻止冒泡的处理
- 搜索功能
二、组件分析
做一个这样的组件,基本的结构如下:

image.png
三、代码实现
- 组件代码
<!-- 添加节点按钮 -->
<el-button @click="addNode">新增</el-button>
<!-- 搜索组件,搜索主要靠watch来进行tree的数据的过滤 -->
<el-input v-model="searchValue" />
<!-- tree组件 -->
<el-tree
<!-- 定义tree对象 -->
ref="tree"
<!-- 虚拟滚动关键属性 -->
height=""
<!-- 数据相关关键定义 -->
node-key=""
:props="{ label: 'label', children: 'children' }"
<!-- 高亮选中节点关键定义 -->
:highlight-current="true"
:current-node-key="currentKey"
<!-- 展开节点关键定义 -->
:default-expanded-keys="expandedKeys"
:auto-expand-parent="true"
<!-- 数据与过滤关键定义 -->
:data="treeData"
:filter-node-method="filterTreeData"
<!-- 节点点击行为控制,主要控制高亮与展开收缩 -->
@node-click="handleNodeClick"
<!-- 其它定义 -->
:indent="0"
>
<!-- 自定义节点 -->
<div class="custom-tree-node" slot-scope="{ node, data }">
<!-- 节点名 -->
<div>{{ node.label }}</div>
<!-- 右侧按钮与阻止冒泡 -->
<div @click.stop><div @click.native="">操作按钮</div></div>
</div>
</el-tree>
...
data () {
return {
// tree定义
currentKey: null,
expandedKeys: [],
treeData: null,
// search
searchValue: '',
// 节点数据结构定义
nodeFormData: {}
}
}
...
watch: {
// tree搜索事件
searchValue (n, o) {
this.$refs.tree.filter(n)
}
}
...
method: {
getTreeData () {
},
filterTreeData () {
},
// 增删改查
}
...
mounted () {
// 获取树数据
this.getTreeData () {
略
},
// 自定义过滤方法
filterTreeData (value, data) {
if (!value) {
return true
} else {
return data.label.indexOf(value) > -1
}
},
// 节点点击控制,主要控制展开、收缩、选中,特别是针对树数据重新渲染之后进行
handleNodeClick (data) {
// 主要包括:
// 1. 展开树节点将节点加入expandKeys并重新控制树的选中
// 2. 收缩树节点将节点从expandKeys中去除并重新控制树的选中
// 3. 点击叶子节点对currentKey进行切换
},
// 重新获取树数据的关键逻辑处理,包括:
1. this.currentKey=
2. this.expandKeys=
3. this.getTreeData().then(() => {
self.$nextTick(() => {
// 设置树的currentKey即可
})
})
}