在有些场景下,一个表格当数据超过表格本身的高度,需要自行滚动,当最后一行数据到底部后会重新回到第一行。
为了考虑灵活性,我们本次将这个方法写成公用的,本以 element-ui 的 Table 组件为例:
我们只需要在相应的表格组件的页面引入此组件,并包上需要滚动的表格组件,在
<AutoScroll ref="autoScroll">
xxxx ... 需要滚动的表格组件
</AutoScroll>
//并在数据拿到后执行组件内部封装的滚动方法
this.$refs.autoScroll.setScroll();
<template>
<div
class="auto-scroll"
ref="scrollTable"
@mouseenter="tableScroll(true)"
@mouseleave="tableScroll(false)"
>
<slot></slot> /* 相当于滚动的表格组件 */
</div>
</template>
<script>
export default {
name: 'AutoScroll',
// 只有组件卸载才会销毁定时器
beforeDestroy() {
clearInterval(this.timer);
},
methods: {
setScroll() {
// 这里采用 $nextTick 是因为正常情况下页面刚挂载完成时,dom元素还拿不到
this.$nextTick(() => {
// 获取包含表格的整个组件
const tableWrap = this.$refs.scrollTable;
// .el-table__body-wrapper 是表格内容的容器
const table = this.$refs.scrollTable.querySelector('.el-table__body-wrapper');
// 这个判断目的是在表格做筛选时,数据会重新拉取,这个组件会被重新执行,但 timer 储存的定时器变量并不会被清空,于是只要是筛选等操作就会让数据重新到第一行开始往下滚动,另一方面也省去了多次清除定时器的过程。
if (this.timer) {
table.scrollTop = 0;
return;
}
// 当前表格显示的高度如果大于等于表格实际内容的高度,表格就不滚动
if (tableWrap.clientHeight - 42 - 12 >= table.scrollHeight) {
return;
}
// 开启定时器每40毫秒让滚动条高度加 1
this.timer = setInterval(() => {
if (this.isStop) {
return;
}
table.scrollTop += 1;
// 如果最后一行的数据滚动到底部就从第一行数据重新开始
if (table.clientHeight + table.scrollTop === table.scrollHeight) {
table.scrollTop = 0;
}
}, 40);
})
},
tableScroll(stop) {
this.isStop = stop;
},
},
};
</script>
<style scoped>
.auto-scroll {
width: 100%;
height: 100%;
}
</style>