element-plus树形数据与懒加载的实现
- 手机
- 2025-08-23 06:27:02

环境
vue版本: 2.6.14
需求
树形表格,默认返回当前登录人拥有权限的一个层级的数据,通过点击load懒加载获取下一层的数据,要求有新增、编辑、删除操作。
树类型的懒加载:
当row中包含children字段时,被视为树形数据。渲染嵌套数据需要prop的row-key。且子节点数据可以异步加载。通过row中的hasChildren字段来指定哪些行是包含子节点。children与hasChildren都可以通过tree-props进行配置。需要设置el-table的lazy属性为true且需要load加载函数,数据懒加载且不可使用 default-expand-all 属性。
代码实现如下:
<el-table ref="tableRef" :loading="loading" :data="tableData" row-key="id" border lazy :load="load" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" > <el-table-column prop="date" label="Date" /> <el-table-column prop="name" label="Name" /> <el-table-column prop="address" label="Address" /> <el-talbe-column label="操作"> <template v-slot="{ row }"> <el-button type="primary" @click="() => add(row.id)">添加</el-button> <el-button type="default" @click="() => edit(row.id)">编辑</el-button> <el-button type="danger" @click="() => delete(row.parentId)">删除</el-button> </template> </el-talbe-column> </el-table> export default { data() { return { tableData: [], loading: false, loadMap: new Map() } }, async mounted() { this.queryTableList(); }, methods:{ async queryTableList() { this.loading = true; // 接口调用获取树形数据 try { const { data, code } = await api.getList({id: undefined}); if(code === 200) { // 将返回的数据结构处理为树形结构 this.tableData = this.processTreeData(data); return this.tableData; } else { return [] } } finally { this.loading = false; } }, processTreeData(data) { return data.map(item => { // 添加hasChildren属性,表示是否有子节点 const hasChildren = item.children && item.children.length > 0; // 递归处理子节点 const children = hasChildren ? this.processTreeData(item.children) : []; // 假如每个节点的类型都是不同的,最后一个子节点的type为last return { ...item, hasChildren: item.type === 'last' ? hasChildren : !hasChildren, children } }) }, async load(tree, treeNode, resolve) { this.loading = true; this.loadMap.set(tree.id, { tree, treeNode, resolve}); try { const { data, code } = await api.getList({id: tree.id}); if(code === 200) { if(data && data.length) { resolve(this.processTreeData(data)) } else { this.$set(this.$refs.tableRef.store.states.lazyTreeNodeMap, tree.id, []) resolve([]) } } else { resolve([]) } } finally { this.loading = false; } }, // 刷新列表 refresh(id) { if(this.loadMap.get(id)) { const { tree, treeMap, resolve } = this.loadMap.get(id); if(tree) { this.load(tree, treeMap, resolve) } } }, // 添加节点 add(id) { // 添加成功后,直接调用 this.refresh(id); }, // 编辑节点 edit(id) { // 根据当前id获取该条数据信息,返回数据中要求有父级的id const parentId = 111; // 父级返回的id this.refresh(parentId); }, // 删除 delete(id) { // 需要传递父级的id this.refresh(id); } } }一、要求最后一个子节点不显示要展开的箭头
item.type === 'last' ? hasChildren : !hasChildren二、当返回的数据为空数组,会导致列表一直显示加载状态。
this.$set(this.$refs.tableRef.store.states.lazyTreeNodeMap, tree.id, [])清空 lazyTreeNodeMap 中的对应数据:在数据为空数组时,手动清空 lazyTreeNodeMap 中对应的数据,这样可以避免加载状态的持续显示。
这个问题的主要原因在于懒加载的机制:懒加载的load函数只在第一次打开子节点时触发,之后不会再次触发,因此数据无法实时刷新。
扩展:将一个子节点迁移至另一个父节点下面
避免遇到的问题:
[Vue warn]: Duplicate keys detected: '111'. This may cause an update error.引起该问题的原因是列表中数据id值重复。
*在迁移数据时,一定要先调用被迁移子节点的父节点,再调用新的父节点获取数据,避免数据冲突。
欢迎在评论区讨论,完善功能代码。
element-plus树形数据与懒加载的实现由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“element-plus树形数据与懒加载的实现”