可以使用以下这种方式来做滚动触底加载,但是官网提示长列表性能不太好,目前也没有更好的方式,暂时先这么处理。
<template>
<scroll-view class="table-container" :scroll-y="true" @scroll="onScrollEvent">
...
</scroll-view>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
props: {
...,
total: {
type: Number,
default: 0,
require: false
}
},
data() {
const timeoutId: NodeJS.Timeout = setTimeout(() => { });
return {
// 父容器高度
parentContainerHeight: 0,
// 定时器初始id
timeoutId,
// 记录上一次滚动时,距离顶部的距离
oldScrollTop: 0,
// 记录上一次滚动时,距离左边的距离
oldScrollLeft: 0
}
},
mounted() {
// 获取表格父容器高度
this.getContainerConfig(`#${this.tableId}`, (data) => {
this.parentContainerHeight = data.height;
});
},
methods: {
/**
* 滚动事件
* @e 滚动时的相关参数
* @scrollHeight 为容器所有列表项的总高
* @scrollTop 距离顶部的距离
* 当前容器 = scrollHeight - scrollTop;
* */
onScrollEvent(e: { detail: { scrollHeight: number; scrollTop: number; scrollLeft: number }; }) {
const { scrollHeight, scrollTop, scrollLeft } = e.detail;
// 如果上一次记录的距离跟当前变化的距离不一致 则表示在向左右滚动 则不执行加载逻辑
if (this.oldScrollLeft !== scrollLeft) return;
// 如果上一次记录的数据 比 当前距离顶部的距离大 则说明是在向上滚动 则不执行加载逻辑
if (this.oldScrollTop > scrollTop) return;
clearTimeout(this.timeoutId);
if (scrollHeight - scrollTop < (this.parentContainerHeight + 50)) {
this.timeoutId = setTimeout(() => {
// 记录每一次滚动时 当前位置跟顶部/左右的距离
this.oldScrollTop = scrollTop;
this.oldScrollLeft = scrollLeft;
// 还没有到底部就继续不断的加载
if (this.sourceData?.length < this.total) {
// 通知父组件去调用接口请求数据
this.$emit('scrollLoadingData');
} else {
// 已经触到了底部
}
}, 200);
}
},
/**
* 根据id来获取到容器的信息
* @id dom元素id
* @fn 回调函数
* */
getContainerConfig(id: string, fn: Function) {
uni.createSelectorQuery().in(this).select(id).boundingClientRect((data) => {
// 回调函数带回参数
fn(data);
}).exec();
},
}
})
</script>
微信小程序官方在scroll-view中也提供了一种触底加载的方式,也没有我写的这么复杂,在uniapp中要改写成vue的方式@scrolltolower
才能生效,两个方式各有优劣,选择适合自己的就行了。
bindscrolltolower eventhandle 否 滚动到底部/右边时触发 1.0.0