乐趣区

关于javascript:iview-table组件懒加载

场景

家喻户晓,iview 的 table 组件,若数据量大的时候,table 组件渲染很慢。为了优化初始化 table 的工夫,不得不做一下优化。

因为,业务需要的起因,此数据表是一个主数据表,不可应用分页 ….

所以只能乖乖的做一下前端的懒加载(也就是分页)

思路

很简略,这里利用二维数组。定义好每个二维数组里要存的个数,而后去保护这个二维数组的下标即可。
申明一个变量: len,代表接口失去的数组长度

  • 每个子数组存入的数量 => len/10
  • 要循环增加的次数 => len/(leng/(len/10))

而后再项数组 push 多个子数组。
之后再去监听 table 的滚动事件,触底之后就触发 loadmore 事件,向初始化数组里 push 残余的子数组;大略思路就是这样。

代码如下
<div class="tale__content">
      <Table :height="tableHeight-30" :loading="loading" :columns="columns" :row-class-name="rowClassName" ref="table"
        :data="tableData">
      </Table>
    </div>
    <Spin fix v-show="spinShow"> 加载中...</Spin>

 async getRateData() {
        this.loading = true;
        const res = await api.getRateList();
        this.loading = false;
        const tableData = res.data.Data || [];
        if (res.data.DetailedStatus === 1) {
          let result = tableData.map(item => {
            return {
              ...item,
              isDisabled: true,
              btnLoading: false,
              isEdit: false
            }
          });
          // 每个子数组存入的数量
          let everyItemLength = Math.ceil(result.length / 10);
          // 要循环增加的次数
          // 因为失去的值有可能不是整数,所以须要向上取整,目标是为了保障最初一次循环不能漏掉
          // 如果失去的值是 5.4,若不向上取整就只循环 5 次,少了一次
          this.averageNum = Math.ceil(result.length / everyItemLength);
          let arr = [];
          let i = 0;
          while (i < this.averageNum) {arr.push(result.splice(0, everyItemLength));
            i++;
          }
          // 默认给 tableData 赋值第一个值
          this.tableData = arr[0];
          //originArr 是残缺的二维数组的值,为了给前面拼接数组的取值用
          this.originArr = arr;
          this.loadmore(this.originArr, this.num)
          setTimeout(() => {this.scrollTable = document.querySelector('.ivu-table-overflowY');
            this.listenScroll();}, 100);
        } else
          this.$dialog(res.data.DetailedMessage)
      },
      listenScroll() {this.$nextTick(() => {
        // 节流函数,不会写的话找度娘
          const {throttle} = this.commonFunction;
          let self = this;
          const listenTableScroll = (e) => {clearTimeout(self.timer)
            if (!self.scrollTable) throw new Error('table 初始化还未实现')
            let scrollTop = self.scrollTable.scrollTop;
            let clientHeight = self.scrollTable.offsetHeight;
            let scrollHeight = self.scrollTable.scrollHeight;
            if (scrollHeight > clientHeight && scrollTop + clientHeight === scrollHeight) {console.log('触底');
              // 如果超出可加载的次数 return 
              if (self.num == self.averageNum - 1) return;
              self.spinShow = true;
              self.timer = setTimeout(() => {
                self.spinShow = false;
                clearTimeout(self.timer)
                self.timer = null;
              }, 4000);
              // 每一次触底,阐明要拼接下一组数据
              self.num++;
              // 调用拼接数组的 loadmore 办法,并且把接口取到的数组和 num 值传过来
              self.loadmore(self.originArr, self.num)
            }
          }
          // 节流监听 table 滚动
          self.scrollTable.addEventListener('scroll', throttle(listenTableScroll, 400));
        })
      },
      handleSpinCustom() {
        this.$Spin.show({render: (h) => {
            return h('div', [
              h('Icon', {
                'class': 'demo-spin-icon-load',
                props: {
                  type: 'ios-loading',
                  size: 18
                }
              }),
              h('div', 'Loading')
            ])
          }
        });
        setTimeout(() => {this.$Spin.hide();
        }, 3000);
      },
      loadmore(list, num) {
        // 如果是 0,阐明是第一次加载,不须要拼接数组,从第二次开始才拼接
        if (num === 0) return
        // 让第一次加载的数组拼接上后续的数组 若需兼容低版本浏览器 换成 concat
        //num 可取出对应下标的二维数组值
        this.tableData = [...this.tableData, ...list[num]];
      },

结构 originArr 和 tableData 的最终后果

这算是一个绝对繁难的计划,后续会持续优化 ….
有问题加 QQ:602353272

退出移动版