关于处理万级数据编辑表格的踩坑日志


1、简介:项目需求要弄一个数据录入表格,数据比较多并且是可编辑,按键切换输入框,左侧固定列等等,一开始表格是直接用的element,用着用着已经不满足需求,编辑数据多的时候慢的不行编辑还卡顿。

2、解决经历:一开始是打算用patch-package修改element源码的,然后发现引入的element引用的是打包后的lib,要改的话需要下载源码修改还要打包设置一个文件并修改引用路径,不然别人拉代码并不会拉到你改过的element,十分麻烦,后来找到了用Vue自定义指令不修改依赖来给element表格打补丁,试过之后发现不行还是很卡顿,之后又找到了umyui表格,说是可以处理万级数据,试了一下感觉还不错,算是不错的解决方案,于是记录一下

2-1、Vue自定义指令修改element渲染的方式(思路是表格只渲染固定的dom,滚动滚动条的时候切换dom的内容)

来源   https://segmentfault.com/q/1010000017202682

作者   Hally

新建一个loadmore.js文件

// 设置默认溢出显示数量
var spillDataNum = 20;

// 设置隐藏函数
var timeout = false;
let setRowDisableNone = function (topNum, showRowNum, binding) {
  if (timeout) {
    clearTimeout(timeout);
  }
  timeout = setTimeout(() => {
    binding.value.call(null, topNum, topNum + showRowNum + spillDataNum);
  });
};

export default {
  name: 'loadmore',
  componentUpdated: function (el, binding, vnode, oldVnode) {
    setTimeout(() => {
      const dataSize = vnode.data.attrs['data-size'];
      const oldDataSize = oldVnode.data.attrs['data-size'];
      if(dataSize === oldDataSize){
        return;
      }
      const selectWrap = el.querySelector('.el-table__body-wrapper');
      const selectTbody = selectWrap.querySelector('table tbody');
      const selectRow = selectWrap.querySelector('table tr');
      if (!selectRow) {
        return;
      }
      const rowHeight = selectRow.clientHeight;
      let showRowNum = Math.round(selectWrap.clientHeight / rowHeight);

      const createElementTR = document.createElement('tr');
      let createElementTRHeight = (dataSize - showRowNum - spillDataNum) * rowHeight;
      createElementTR.setAttribute('style', `height: ${createElementTRHeight}px;`);
      selectTbody.append(createElementTR);

      // 监听滚动后事件
      selectWrap.addEventListener('scroll', function () {
        let topPx = this.scrollTop - spillDataNum * rowHeight;
        let topNum = Math.round(topPx / rowHeight);
        let minTopNum = dataSize - spillDataNum - showRowNum;
        if (topNum > minTopNum) {
          topNum = minTopNum;
        }
        if (topNum < 0) {
          topNum = 0;
          topPx = 0;
        }
        selectTbody.setAttribute('style', `transform: translateY(${topPx}px)`);
        createElementTR.setAttribute('style', `height: ${createElementTRHeight-topPx > 0 ? createElementTRHeight-topPx : 0}px;`);
        setRowDisableNone(topNum, showRowNum, binding);
      })
    });
  }
};

 在main.js里面引入

import loadmore from '@/js/loadmore'
Vue.directive(loadmore.name,loadmore.componentUpdated);

然后在页面使用





 2-2、umy-ui表格(有很详细的文档)

官网:http://www.umyui.com/

github:https://github.com/u-leo/umy-ui