场景
众所周知,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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。