优化elemen-ui的el-table的tree树结构因数据过多卡顿问题

最近遇到一个要在elemen-ui的el-table放一个树结构的表数据
但是因为数据实在过多,而且列也有四五列,还有操作列
dom操作频繁导致页面非常的卡顿

网上看了很多种方法以及elementui的官方方法
使用lazy和load方法终于解决

2024-06-06

1、新增了默认展开第一层级的方法。
2、新增对树进行新增修改时,数据树进行局部刷新

这里另一篇解决新增修改不刷新问题

https://blog.csdn.net/qq_44179024/article/details/138350719?spm=1001.2014.3001.5502

这篇文章大多数是参考的网上很多大佬的,所谓站在巨人的肩膀上,所以不一定适用每一个人,也不一定能实现大家的需求,只是给大家一个参考哈,同时也感谢这些大佬的文章解决我的问题,感谢感谢。我这里只是整合一下关于这个树我遇到的问题和网上的一些适合我的解决方法,后期还有问题再上来改改。

对应el-table

<el-table v-if="refreshTable" v-loading="loading" :data="list" row-key="id" ref="multipleTable" lazy :load="load" :tree-props="{children: 'children', hasChildren: 'hasChildren'}" :expand-row-keys="expandRowKeys">

一、获取后端数据

1、使用到的data数据

list: [],
listCopy: [],
maps: new Map(),
expandRowKeys: [],

设置一个list展示 为了不全部渲染导致页面卡顿,将list的children数据置空,
再设置hasChildren 为true表示有展开数据

2、完全拷贝一份数据 listCopy 保存下来,后面查找子节点

getList() {
      this.loading = true;
      //获取后端接口数据
      listOrgAll(this.queryParams).then(res => {
        this.list = res.data
		this.listCopy = JSON.parse(JSON.stringify(res.data)) // 备份的全量数据
		this.list.map(item => {
			if(item.children.length > 0) {
				item.hasChildren = true
				item.children = []
			}

		})
        this.loading = false;
      });
    },

3、2024-06-06修改 获取初始数据时,判断是否有搜索条件

getList() {
      this.loading = true;
      listOrgAll(this.queryParams).then(res => {
        this.list= res.data
		this.listCopy = JSON.parse(JSON.stringify(res.data)) // 备份的全量数据
		//这里判断时候是有搜索条件
		if(this.queryParams && (this.queryParams.status || this.queryParams.name) ) {
			this.list= res.data
		} else {
			this.list.map(item => {
				item.hasChildren = true
				//这里我又循环了一遍把第二层级的子节点置空,因为我需要默认打开第一层级的数据
				item.children.forEach(i => {
					i.hasChildren = true
					i.children = []
				})
			})
			// 用来设置初始时,展开第一层级的数据
			this.openTreeHandle(this.list)
		}
        this.loading = false;
      });
    },

这里新增了一个openTreeHandle的方法,因为需求需要显示到第二层级的数据,
之前试了很多方法

考虑1:把第二层级以下数据全部置空,设置default-expand-all全部展开,但是左边展开折叠的箭头显示不出来,且无法点击获取下一层级的数据
考虑2: 使用官方文档的toggleRowExpansion,我觉得看官方文档的描述是可以实现的,但是我的没成功,有空我再试试看
考虑3:因为考虑到上面改数据的情况,会出现很多箭头出现或者箭头方向问题,所以就想,有没有一种方法能在初始的时候,能自动点击一下第一层级的数据,这样就能实现了。
然后就看到了这篇文章
基本添加了这个大佬的这个方法就可以了

https://gitcode.csdn.net/6628ae7716ca5020cb590674.html?dp_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MTQ3MjE4MywiZXhwIjoxNzE4MjUwNTQ2LCJpYXQiOjE3MTc2NDU3NDYsInVzZXJuYW1lIjoicXFfNDQxNzkwMjQifQ.HgbLdTR2bp72QnWCjh73Iu_R-g3AGmy5hLVuhI0XcvM

// 打开树的层级
	 openTreeHandle(deptList) {
		const id = deptList ? deptList.map(item => (item.id).toString()) : []
		this.expandRowKeys = this.expandRowKeys.concat(id)
		const els = document.getElementsByClassName('el-table__expand-icon el-table__expand-icon--expanded')
		this.$nextTick(() => {
			if (els.length > 0) {
				for (let i = 0; i < els.length; i++) {
					els[i].click()
				}
			}
		})
	},

4、新增

二、load方法

递归查找备份的全量数据,找到对应的children数据,将children数据返回

// 树结构获取数据
load(tree, treeNode, resolve) {
		// 查找子节点数据
		function findNodeById (node, id) {
			// 找到对应id数据
			if (node.id === id) {
				// 拷贝当前节点数据
				const newNode = { ...node };
				if (newNode.children && newNode.children.length > 0) {
					// 修改查找到的对应id的children数据,把找到的数据里面的children数据置空,并设置hasChildren
					newNode.children = newNode.children.map(child => {
						return {
							...child,
							// 设置hasChildren判断是否显示展开按钮
							hasChildren: child.children.length >0 ? true : false,
							children: []  // 置空子节点
						};
					});
				}
				return newNode.children;
			}
			// 递归查找每一层的children数据
			if (node.children && node.children.length > 0) {
				for (let i = 0; i < node.children.length; i++) {
					const result = findNodeById(node.children[i], id);
					if (result) {
						return result;
					}
				}
			}
			return null;
		}
		const foundNode = findNodeById(this.listCopy[0], tree.id);
		//设置map值,记录当前展开的值,方便后期新增/修改对应行值时修改数据
		this.maps.set(tree.id, { tree, treeNode, resolve })
		resolve(foundNode)
	},
  • 9
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值