使用了 elementUI 中的 el-table 组件,不使用分页,当表格数据过多时导致页面卡顿;
解决该问题主要是用虚拟滚动的思路。引发页面卡顿的原因主要是由于数据量太大导致渲染的 dom 较多,然后页面就卡顿了。
下面使用 element 中的 el-table 实现一下虚拟滚动来解决这个问题

1 页面结构
<template> <div> <div class="gl-cell-card-box"> <el-table ref="tableRef" style=
"width:418px" border max-height="448" :data="sliceTable" :row-key="row =>
row.id" @select="handleSelect" @select-all="handleSelectAll" > <el-table-column
type="selection" width="40"> </el-table-column> <el-table-column prop="name"
label="姓名" width="120"></el-table-column> <el-table-column prop="age" label="年龄"
width="120"></el-table-column> <el-table-column prop="address" label="住址"></el-
table-column> </el-table> </div> </div> </template>
2 定义一些变量
data() { return { // 表格所有数据 tableData: [], // 开始索引 startIndex: 0, // 选中的数据
selectedRows: [], // 空元素,用于撑开table的高度 vEle: undefined, // 是否全选 isSelectedAll:
false, }; },
3 定义方法
// 计算属性 computed: { // 这个是截取表格中的部分数据,放到了 table 组件中来显示 sliceTable() { return
this.tableData.slice(this.startIndex, this.startIndex + 9); }, }, created() {
// 创建一个空元素,这个空元素用来撑开 table 的高度,模拟所有数据的高度 this.vEle = document.createElement(
"div"); this.loadData(); }, mounted() { // 绑定滚动事件 this.$refs.tableRef.$el .
querySelector(".el-table__body-wrapper") .addEventListener("scroll", this.
tableScroll, { passive: true }); }, methods: { // 加载数据 loadData() { let start_i
= this.tableData.length; for (let i = start_i; i < start_i + 20; i++) { this.
tableData.push({ id: i, name: "zhangsan" + i, age: 12, address: "china" }); }
this.$nextTick(() => { // 设置成绝对定位,这个元素需要我们去控制滚动 this.$refs.tableRef.$el.
querySelector(".el-table__body").style.position = "absolute"; // 计算表格所有数据所占内容的高度
this.vEle.style.height = this.tableData.length * 48 + "px"; //
把这个节点加到表格中去,用它来撑开表格的高度 this.$refs.tableRef.$el.querySelector(
".el-table__body-wrapper").appendChild(this.vEle); // 重新设置曾经被选中的数据 this.
selectedRows.forEach(row => { this.$refs.tableRef.toggleRowSelection(row, true);
}); }); }, /** * @description: 手动勾选时的事件 * @param {*} selection - 选中的所有数据 *
@param {*} row - 当前选中的数据 * @return {*} */ handleSelect(selection, row) { this.
selectedRows= selection; }, /** * @description: 全选事件 * @param {*} selection *
@return {*} */ handleSelectAll(selection) { this.isSelectedAll = !this.
isSelectedAll; if (this.isSelectedAll) { this.selectedRows = this.tableData; }
else { this.selectedRows = []; this.$refs.tableRef.clearSelection(); } }, /** *
@description: table 滚动事件 * @param {*} * @return {*} */ tableScroll() { let
bodyWrapperEle= this.$refs.tableRef.$el.querySelector(".el-table__body-wrapper")
; // 滚动的高度 let scrollTop = bodyWrapperEle.scrollTop; // 下一次开始的索引 this.startIndex
= Math.floor(scrollTop / 48); // 滚动操作 bodyWrapperEle.querySelector(
".el-table__body").style.transform = `translateY(${this.startIndex * 48}px)`;
// 滚动操作后,上面的一些 tr 没有了,所以需要重新设置曾经被选中的数据 this.selectedRows.forEach(row => { this.
$refs.tableRef.toggleRowSelection(row, true); }); // 滚动到底,加载新数据 if (
bodyWrapperEle.scrollHeight <= scrollTop + bodyWrapperEle.clientHeight) { if (
this.tableData.length == 100) { this.$message.warning("没有更多了"); return; } this.
loadData(); } } }

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信