element中el-table大数据量渲染卡顿问题
·
最终实现效果
1、业务描述
在开发过程中,一个表格需要无分页展示出几万条的数据。并且表格有几十甚至一百多列。
2、现象及问题原因
正常使用el-table渲染表格页面直接卡死。
一次性渲染了几万条,几十列,造成大量DOM一次性渲染,直接造成至使页面卡死。
曾尝试使用组件unmy-ui解决卡顿问题,但效果不显著…
3、解决方案
采用数据结合盒子滚动实现数据动态滚动效果。
思路:动态替换可视区域的数据。
我所写的案例是默认展示十条,接下来按十条描述。
主体内容显示部分:页面默认进入显示的是第一个十条,也就是索引的[0,9]。当盒子滚动的时候滚动了一行默认显[1,10],两行[2,11]…以此类推。
这个位置永远都是只展示十条。
滚动盒子:计算出来当前所有数据的高度(为了方便计算行高默认相同,案例中行高45px),以便于撑起来盒子高度,显示滚动条。
ps:目前存在一个问题,鼠标必须在滚动条的盒子上移动才会有效果。这个有待研究…
画了一图展示下层叠关系
如果使用触底懒加载方式,也会因为DOM加载过多造成页面卡顿。
4、代码部分
代码很全也很简单,运行一下就能看明白。滚动向上滚动向下都能根据位置自动显示对相应数据。
<template>
<div class="box">
<!-- false-box这是一个用来显示滚动条的方法 -->
<div class="false-box">
<div class="scroll-box" :style="{'height': scollBoxHeight + 'px'}">
<!-- scroll-box是用来撑起盒子的方法 -->
</div>
</div>
<div class="table-box">
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
export default {
data() {
return {
allData:[],
tableData: [],
elTableHeight: '', //el-table的高度
theadHeight: '', //表头的高度
contentHeight: 0, //主要内容高度
showRowCount: 0, //一共能显示多少行
falseBox: 0, //后边假盒子的高度
scollBoxHeight: 0, //假滚动条的高度
scrollTopRowCount: 0, //一共向上滚动了多少行
}
},
mounted() {
let that = this;
// 模拟一万条假数据
for(let i = 0; i < 10000; i++) {
this.allData.push({
date: i+ 1,
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
})
}
this.scollBoxHeight = 45 * this.allData.length + 45; //多加一行,要不然滚动到底差一行
this.$nextTick( () => {
this.elTableHeight = document.querySelector('.table-box .el-table').offsetHeight;
this.theadHeight = document.querySelector('.table-box .el-table__header-wrapper').offsetHeight;
this.contentHeight = this.elTableHeight - this.theadHeight;
this.showRowCount = Math.floor(this.contentHeight / 45);
// 获取默认显示的前 <showRowCount> 条
this.tableData = JSON.parse(JSON.stringify(this.allData)).splice(0,this.showRowCount);
})
this.falseBox = document.querySelector('.false-box');
this.falseBox.addEventListener('scroll', function(e) {
that.scrollTopRowCount = Math.ceil(e.target.scrollTop / 45);
// 获取从索引<scrollTopRowCount> 开始 <showRowCount> 条
that.tableData = JSON.parse(JSON.stringify(that.allData)).splice(that.scrollTopRowCount, that.showRowCount);
});
},
}
</script>
<style lang="scss" scoped>
.box {
width: 1000px;
height: 500px;
overflow: hidden;
position: relative;
.false-box {
width: 100%;
height: 100%;
position: absolute;
top: 0%;
left: 0%;
overflow: auto;
.scroll-box {
width: 100%;
height: 1000px;
position: absolute;
top: 0%;
left: 0%;
}
}
.table-box {
width: calc(100% - 20px);
height: 100%;
position: absolute;
top: 0%;
left: 0%;
}
}
::v-deep .el-table {
width: 100%;
height: 100%;
.el-table__row {
height: 45px;
td {
padding: 0px
}
}
}
</style>
更多推荐
已为社区贡献1条内容
所有评论(0)