背景:dom加载太多,导致动画卡顿。
解决方案一:使用分页、Virtualized Table
解决方案二:监听触底和触顶,懒加载数据 固定dom节点数量
现在使用解决方案二实现一下:
<template>
<el-table ref="TableRef" id="TableId" :data="sliceTable" stripe style="width: 100%" :height="320">
<el-table-column prop="Index" label="序号" width="180" />
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="address" label="Address" />
</el-table>
</template>
<script setup>
let tableData = [];
const state = reactive({
startIndex: 0,
endIndex: 0,
showDataLength: 20
})
for (let i = 1; i <= 100; i++) {
tableData[i] = {
Index: i,
date: '2016-05-03',
address: 'No. 189, Grove St, Los Angeles',
}
}
const sliceTable = computed(() => {
return tableData.slice(state.startIndex, state.startIndex + state.showDataLength)
})
const TableRef = ref();
// 滚动行为
function scrollBehavior(e) {
// 清除之前的定时器
clearTimeout(timer)
// 设置新的定时器
timer = setTimeout(() => {
// 滚动方向判定
const scrollDirection = e.deltaY > 0 ? 'down' : 'up'
// 获取提供实际滚动的容器
const dom = TableRef.value.$refs.bodyWrapper.getElementsByClassName('el-scrollbar__wrap')[0]
const { clientHeight, scrollTop, scrollHeight } = dom;
if (scrollDirection === 'down') {
// 父容器高度 + 子容器距离父容器顶端的高度 = 子容器可滚动的高度
if (clientHeight + scrollTop === scrollHeight) {
if (state.startIndex < tableData.length - state.showDataLength) {
state.startIndex += state.showDataLength;
dom.scrollTop = 0;
}
}
} else {
if (scrollTop == 0) { // 滚动到顶部
if (state.startIndex >= state.showDataLength) {
state.startIndex -= state.showDataLength;
dom.scrollTop = 0; // 将滚动位置重置到底部
}
}
}
}, debounceTime)
}
const debounceTime = 500
let timer = null
onMounted(() => {
// 挂载
TableRef.value && TableRef.value.$refs.bodyWrapper.addEventListener('mousewheel', scrollBehavior)
})
onUnmounted(() => {
// 卸载
TableRef.value && TableRef.value.$refs.bodyWrapper.removeEventListener('mousewheel', scrollBehavior)
})
</script>