解决ElementUI列表大数据操作卡顿问题

问题描述

前端UI框架使用的是ElementUI,项目要求数据不分页一个表格至少要1000条数据,这时点击其他DOM操作,会出现卡顿的现象。如点击复选框。

官网的示例也搞了,超过200行后操作就会卡很久,比如复选框

基于elementUI的table,在不修改源码的情况下支持大数据了渲染的场景

思路:

减少对DOM节点的渲染,通过滚动函数节流实现滚动后事件来动态渲染数据

解决方案:

Vue自定义指令 (通过自定义指令隐藏数据)

ele-table

  
    
      
      
      
        
          
            
            {{ scope.row.date }}
          
        
      
      
        
          
            
            {{ scope.row.date }}
          
        
      
      
        
          
            
            {{ scope.row.date }}
          
        
      
      
        
          
            
            {{ scope.row.date }}
          
        
      
      
        
          
            
              

姓名: {{ scope.row.name }}

住址: {{ scope.row.address }}

{{ scope.row.name }} 编辑 删除 export default { name: 'test', components: {}, data () { return { tableData: [], currentStartIndex: 0, currentEndIndex: 20 }; }, created () { this.getTableData(); }, computed: { filteredData () { return this.tableData.filter((item, index) => { if (index this.currentEndIndex) { return false; } else { return true; } }); } }, methods: { handelLoadmore (currentStartIndex, currentEndIndex) { this.currentStartIndex = currentStartIndex; this.currentEndIndex = currentEndIndex; }, getTableData () { let cont = 0; let tableData = []; while (cont { this.tableData = tableData; }, 2000); } }, watch: {} } .el-table__body-wrapper .el-table__row td { display: none; } .el-table__body-wrapper .el-table__row { height: 38px; }

指令代码:

// 设置默认溢出显示数量
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 ? createElementTRHeight-topPx : 0}px;`);
        setRowDisableNone(topNum, showRowNum, binding);
      })
    });
  }
};

全局main.js引用

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

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/62d970e579.html