最近做的项目数据量比较大,需要分页请求数据。且均要求滚动条触底时请求下一页数据。网上找了一些资源但都不太合适,踩了好多坑,终于通过简单的方法实现了。
Elementplus 表格触底刷新的方法:
<script>
//触底函数
function handleScroll(event:any){
const {target} = event;
//当滚动条距离顶部的距离(scrollTop)加上表格本来的高度(clientHeight)大于元素内容高度(包括由于溢出导致的视图不可见内容,scrollHeight)时,即发生触底
if(Math.ceil(target.scrollTop+target.clientHeight+1)>target.scrollHeight){
}
}
onMounted(() => {
//获取dom元素,一定要开启捕获,否则可能获取不到。当然表格中含有多个可滚动元素时也可能无法准确监测
document.querySelector(".el-table__body-wrapper")?.addEventListener("scroll", handleScroll,true);
});
onBeforeUnmount(() => {
document.querySelector(".el-table__body-wrapper")?.removeEventListener("scroll", handleScroll,true);
});
</script>
具体复杂的逻辑大家可以自己实现。
实际上,很多时候触发不了滚动事件,可以开启事件捕获,利用浏览器先捕获后冒泡的机制就能成功监测到。
echarts折线图触底刷新的方法:
项目中我用的是折线图,由于获取到的整个折线图是个canvas,无法利用事件捕获的特性来监测滚动。
但实际上echarts本身暴露了方法给我们。
<script>
//首先在options配置中开启滚动条
let options={
....,
dataZoom: [
{
// 设置滚动条的隐藏与显示
show: true,
// 设置滚动条类型
type: "slider",
// 设置背景颜色
backgroundColor: "rgb(19, 63, 100)",
// 设置选中范围的填充颜色
fillerColor: "rgb(40, 106, 138)",
// 设置边框颜色
borderColor: "rgb(19, 63, 100)",
// 是否显示detail,即拖拽时候显示详细数值信息
showDetail: false,
// 数据窗口范围的起始数值
startValue: 0,
// 数据窗口范围的结束数值(一页显示多少条数据)
endValue: 15,
// empty:当前数据窗口外的数据,被设置为空。
// 即不会影响其他轴的数据范围
filterMode: "empty",
// 设置滚动条宽度,相对于盒子宽度
width: "50%",
// 设置滚动条高度
height: 5,
// 设置滚动条显示位置
left: "35%",
// 是否锁定选择区域(或叫做数据窗口)的大小
zoomLoxk: true,
// 控制手柄的尺寸
handleSize: 0,
// dataZoom-slider组件离容器下侧的距离
bottom: 3,
},
{
// 没有下面这块的话,只能拖动滚动条,
// 鼠标滚轮在区域内不能控制外部滚动条
type: "inside",
// 滚轮是否触发缩放
zoomOnMouseWheel: false,
// 鼠标滚轮触发滚动
moveOnMouseMove: true,
moveOnMouseWheel: true,
},
]
}
</script>
监测滚动条滚动
<script>
onMounted(() => {
mylineechart.on('dataZoom', handelScroll); //mylineechart换成表格初始化设置的变量
})
function handelScroll(params:any){
//可以console.log看一下,滚轮滚动和按下鼠标滚动的params不一致。这里我都进行判断了
if(params.end===100||params.batch?.[0]?.end===100){
}
}
</script>
就这样实现简单的触底判断了。对于echarts中的请求更多数据后滚动条直接滚到最后的问题,可以在dataZoom中配置:
<script>
watch(...,()=>{
//更改滚动条位置
options.dataZoom[0].startValue=(pageNo-1)*pageSize
options.dataZoom[0].endValue=(pageNo-1)*pageSize+每次想看到的数量
mylineechart.setOption(options,true)
})
</script>