千家信息网

怎么解决Element的穿梭框数据量大时点击全选卡顿问题

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容介绍了"怎么解决Element的穿梭框数据量大时点击全选卡顿问题"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅
千家信息网最后更新 2026年11月02日怎么解决Element的穿梭框数据量大时点击全选卡顿问题

本篇内容介绍了"怎么解决Element的穿梭框数据量大时点击全选卡顿问题"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

现象:我们渲染了9999条数据,由于transfer组件会一次性渲染所有数据,所以一次性渲染这么多,卡个几十秒很正常好吧。所以懒加载或者分页是基本操作,方案二是分页操作。

懒加载的方式可以用EUI的无限滚动

即便我们做了懒加载之后,点击全选依旧是卡顿6秒以上,所以方案一解决的是:即便做了懒加载或者分页操作后,用户点击分页,依旧会卡顿几秒的情况。

这个是因为transfer的源码中'全选判断'代码性能差的原因,方案一就是修改transfer的源码。

我提交了一个pr,地址是: hhttps://github.com/ElemeFE/element/pull/20282

方案一:复制EUI的transfer组件,然后进行修改,再引入项目目录

EUI的transfer组件目录路径:node_modules\element-ui\packages\transfer,复制文件夹,然后放入vue项目路径的

在调用EUI的transfer的地方引入公共的组件transfer,

开始修改transfer代码:

打开src/common\transfer\src\transfer-panel.vue的组件,

找到updateAllChecked函数,updateAllChecked函数作用是:我们点击一个item就需要判断,看代码注释。

updateAllChecked() {      /*        源码        this.checkableData是对象数组  我们需要的是每个对象中的key        所以checkableDataKeys保存着对象的key的数组 含义是'可通过点击进行选择的item项'的集合      */      let start = new Date().getTime();      const checkableDataKeys = this.checkableData.map(        item => item[this.keyProp]      );      this.allChecked =        checkableDataKeys.length > 0 &&      /*        从2.4.0到现在都没改变 诶,不得不说开发团队是真的忙啊        this.checked保存着'用户通过点击item选中的item数组'        如果this.checked存在着checkableDataKeys的每一项的话,那么allChecked就是true,但凡有一项不存在就为false。allChecked代表是否全部选中了。        这里的时间复杂度是n^2,狠垃圾      */      checkableDataKeys.every(item => this.checked.indexOf(item) > -1);      console.log("updateAllCheckedEnd", new Date().getTime() - start);    },

来看源码的耗时:

然后我们开始重写updateAllChecked函数:

updateAllChecked() {      /*        修改        这里就是高效数组中含有另一个数组的元素的算法        构建元素对象      */      let start = new Date().getTime();      let checkableDataKeys = this.checkableData.map((item) => {        let keyProps = {};        keyProps[item[this.keyProp]] = true;        return keyProps;      });      // 通过对象的k-v对应,n(1)的方式寻找数组中是否存在某元素      this.allChecked =        checkableDataKeys.length > 0 &&        this.checked.length > 0 &&        this.checked.every((item) => checkableDataKeys[item]);      // 上面被注释的源码是最耗时的,所有一直看耗时就可以了      console.log("updateAllCheckedEnd", new Date().getTime() - start);    },

这样性能就高好多了,其实就是基本的前端算法题,目测EUI的开发者是因为懒才不写的。

来看修改代码后的耗时:

明显快多了。

接下来是文件:\src\common\transfer\src\main.vue,找到addToRight函数

addToRight() {      let currentValue = this.value.slice();      const itemsToBeMoved = [];      const key = this.props.key;      let start = new Date().getTime();      // 此处套了两层循环,耗时长      this.data.forEach((item) => {        const itemKey = item[key];        if (          this.leftChecked.indexOf(itemKey) > -1 &&          this.value.indexOf(itemKey) === -1        ) {          itemsToBeMoved.push(itemKey);        }      });      console.log("addToRightEnd", new Date().getTime() - start);      currentValue =        this.targetOrder === "unshift"          ? itemsToBeMoved.concat(currentValue)          : currentValue.concat(itemsToBeMoved);      this.$emit("input", currentValue);      this.$emit("change", currentValue, "right", this.leftChecked);    },

移动选中的耗时:

修改addToRight函数,

addToRight() {      let start = new Date().getTime();      let currentValue = this.value.slice();      const itemsToBeMoved = [];      const key = this.props.key;      // 修改      let leftCheckedKeyPropsObj = {};      this.leftChecked.forEach((item, index) => {        leftCheckedKeyPropsObj[item] = true;      });      let valueKeyPropsObj = {};      this.value.forEach((item, index) => {        valueKeyPropsObj[item] = true;      });      this.data.forEach((item) => {        const itemKey = item[key];        if ( leftCheckedKeyPropsObj[itemKey] && !valueKeyPropsObj[itemKey] ) {          itemsToBeMoved.push(itemKey);        }      });      console.log("addToRightEnd", new Date().getTime() - start);      currentValue =        this.targetOrder === "unshift"          ? itemsToBeMoved.concat(currentValue)          : currentValue.concat(itemsToBeMoved);      this.$emit("input", currentValue);      this.$emit("change", currentValue, "right", this.leftChecked);    },

移动选中耗时:

耗时明显减少了,这方案的前提就是懒加载或者分页,我试了一下10w的数据量,依旧是不错的。

方案二:分页操作

分析

checkBox-group有个check数组(用来记录已经选中的item数组)和renderItem数组(实际渲染的item,由于是分页,所有不会渲染所有),如果`check数组`中有`renderItem数组`的一项,那么该项就会被标记为已选,否则是未选。实现原理就是单纯的check数组和renderItem数组进行比较。

当用户点击全选的时候,check数组变成上万条数据的数组,此时我们渲染了100条数据,那么就要进行10000x100级别的循环,这就是耗时的原因所在。

其实,页面只渲染了100条数据,我们没必要将上万条数据一次性放入check数组中,我们只需要把这100条数组放入check数组,显示这100条数据为已选即可。当页面渲染了更多数据的同时,将新增的数据添加进check数组即可。这样性能大大提升。

方案

我采用的方案如下:

1.只显示100条数据。

2.下拉显示下100条数据,上拉显示上100条数据。

3.当下拉或者上拉增加渲染数据的同时,把新增数据添加进check数组。

这些只是大致思路,我已经实现了。还有很多细节要处理,想要完善,还得利用对象的键值对实现删除等。

"怎么解决Element的穿梭框数据量大时点击全选卡顿问题"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

数组 数据 就是 方案 对象 函数 源码 组件 卡顿 代码 一次性 元素 性能 更多 用户 问题 明显 接下来 万条 内容 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 百单网互联网科技有限公司 哈尔滨大商圈互联网科技有限公司 互联网是第几次科技革命的成果 金融科技 互联网金融 互联网科技公司电话 未来的互联网科技 互联网科技博客 多迪互联网科技有限公司 镁科技互联网资讯平台 科技与互联网哪个更好 千方科技属于互联网企业吗 互联网媒体平台算高科技产业 科技类公司包括互联网吗 美国互联网科技实力 黑科技 体验场景 互联网大会 中国新注册互联网科技 广西科技产业互联网是什么 互联网领先科技活动 互联网大会出现的黑科技 知域互联网科技有限公司官网 咖啡 北京路客互联网科技有限公司 奇酷互联网科技 礼当家互联网科技 北京大学互联网科技怎么样 知域互联网科技有限公司大骗子 注册互联网科技公司经营范围大全 为客找房互联网科技公司怎么样 互联网金融科技元年 每天都有哪些好的互联网科技
0