likes
comments
collection
share

老项目优化之:如何给Avue库的Crud表格组件开启虚拟滚动?写在前面 公司有个老项目用的是Vue2 + avue组件库

作者站长头像
站长
· 阅读数 28

写在前面

公司有个老项目用的是Vue2 + avue组件库,里面大量的表格使用avuecrud组件,在遇到每页200500的大量数据时,全选,分页就会卡卡卡卡个不停,领导也早早提了优化需求,一直在待办里躺着。

时不时有用户反馈表格卡,再不时表格反映慢,用户对于表格的吐槽不绝于耳。

终于在项目不那么紧张的时间段里,这个老问题再次沉渣又泛起,在我心中激起阵阵涟漪, 久久不能平复,是时候展示真正的技术了

看我如何:

十步灭一bug,千里不留行。

开始正文

表格卡顿,又是二次封装的复杂表格,从源码角度优化是一个方案,直接在现有二次封装组件上添加虚拟滚动之类的优化另一个方案;鉴于目测avue组件的复杂性,果断选择走第二条路。

百度必应各种搜索之后确定一个适合Vue2的库:el-table-virtual-scroll

选定的依据:

  1. 支持Vue2;
  2. 虚拟滚动可以显著提高表格性能;
  3. 虚拟滚动组件全选

选定那就开搞吧,看看vue2老牌avueel-table-virtual-scroll之间能擦出怎样的火花呢?

el-table-virtual-scroll基本用法

安装

npm i el-table-virtual-scroll

使用


<virtual-scroll
  :data="list"
  :item-size="62"
  key-prop="id"
  @change="(renderData) => virtualList = renderData">
  <avue-crud 
    :option="option"
    :table-loading="loading"
    :data="virtualList"
    :page="page"
    :pageTotal="pageTotal"
    v-model="form"
    ref="crud"
    ...
  />
</virtual-scroll>
...

import VirtualScroll from 'el-table-virtual-scroll'

export default {
  component: {
    VirtualScroll
  },
  data () {
    list: [
      {
        id: 1,
        text: 'content'
      },
      // ...... 省略n条
      {
        id: 2000,
        text: 'content2'
      }
    ],
    virtualList: []
  }
}

可以看到代码比较简单,通过virtual-scroll接管el-table的全部data数据,然后通过change事件更新当前需要渲染的数据。

很快啊,遇到了第一个问题

表格没有数据展示,先是推测change事件没有执行,再发现控制台有报错,大概意思是说没找到el-table组件, 我不禁要疑惑了,难道二次封装过的el-table不支持??

随后向上看了几眼el-table-virtual-scroll源码,让我发现了一个宝藏方法getElTable,对比文档,发现这个方法正是针对我们这些被封装过的el-table场景,真实太好了。

老项目优化之:如何给Avue库的Crud表格组件开启虚拟滚动?写在前面 公司有个老项目用的是Vue2 + avue组件库

为作者点赞哈❤️❤️❤️

当然把这个方法加上看看效果:

getElTable(){
   return this.$refs.crud.$refs.table;
},

正当我满心欢喜,以为找到了病根的时候,不出意外的意外就发生了,还是报找不到el-table实例。

这就尴尬了,在getElTable里打印this.$refs.crud.$refs.table时,发现输出undefined,难受了,是不是avue筛选项太多了导致getElTable执行的时候表格还没渲染?

怎么办??就这样放弃了?

继续漫无目的地在el-table-virtual-scroll源码淘宝,发现几个可能有用的方法,initDataupdateupdateData,那在表格数据初始化的时候调一下这三个方法:

this.data = res.data.list;
this.$refs.virtualScroll.initData();
//this.$refs.virtualScroll.doUpdate()
//this.$refs.virtualScroll.updateData(this.data)

成了,就这么成了?好奇到底是哪个方法成了呢,一个一个尝试发现是initData方法发挥了效果,查看源码发现initData里调用了getElTable,此时拿到el-table也是顺理成章的事了。

开心,以后马上就能结束战斗的时候,遇到了本次优化中最大一个问题?

多选,怎么做?按el-table-virtual-scroll的例子选择框需要这样实现:

<virtual-column type="selection" width="60"></virtual-column>
...

<script> 
import VirtualScroll from 'el-table-virtual-scroll' 
import { VirtualColumn } from 'el-table-virtual-scroll' 
export default { 
    components: { VirtualScroll, VirtualColumn },
...

这里用到另一个组件virtual-column, 也就是el-table-virtual-scroll需要接管el-table的多选,这也能理解,毕竟表格开启虚拟滚动只渲染了一部分数据,表格自己全选的话只能选择几个。

问题是avue的columns都是options配置式,虽然支持插槽,试了selection插槽没有效果

咋办?前进还是后退这是个问题?

不行,改avue源码吧,脑海里产出这样一个念头,那就死马当活马医好了,先看看源码再说:

老项目优化之:如何给Avue库的Crud表格组件开启虚拟滚动?写在前面 公司有个老项目用的是Vue2 + avue组件库

找到selection配置项的地方,从外面传入一个selectionComponent='virtual-column',当然直接这样写并没有成功,随后在脑海里复盘组件渲染机制,找到了一个可疑点:virtual-column局部引入的,avue在渲染时应该拿不到局部引入的组件,改成全局引入试试:

Vue.component("virtual-scroll", VirtualScroll);
Vue.component("virtual-column", VirtualColumn);

完美!!!运行成功。

至此皆大欢喜,顺利运行,滚动很流畅,全选也很快...

老项目优化之:如何给Avue库的Crud表格组件开启虚拟滚动?写在前面 公司有个老项目用的是Vue2 + avue组件库

尾声

事了拂衣去,深藏功与名。

最后还遇到一个问题:

重新搜索后,已选项里还包括上一次的选择结果,这也很简单,在搜索时清空选项就可以: this.$refs.virtualScroll.clearSelection();

谨以此文纪念那些经历一波三折最后被解决掉的BUG。

转载自:https://juejin.cn/post/7400582230802759720
评论
请登录