vue3 触底加载hooks
import { onUnmounted, ref } from 'vue'
/**
* onReachBottomFn :滚动加载函数
* reachBottomDistance : 距离底部多少距离时触发
*/
function useScrollBottom(onReachBottomFn, reachBottomDistance = 100) {
const isReachBottom = ref(false)
let scrollListenerAttached = false
let elementRef = null
let moreQueryParams = ref({})
const onScroll = async () => {
if (elementRef) {
const scrollTop = elementRef.scrollTop
const scrollHeight = elementRef.scrollHeight
const clientHeight = elementRef.clientHeight
const currentHeight = scrollTop + clientHeight
const isAtBottom = currentHeight + reachBottomDistance >= scrollHeight
if (isAtBottom && !isReachBottom.value) {
// 调用传入的触底触发函数 bool 值代表是否还有更多数据
const isEnd = await onReachBottomFn(moreQueryParams.value)
isReachBottom.value = isEnd
}
}
}
const attachScrollListener = async (ele) => {
elementRef = ele
if (elementRef && !scrollListenerAttached) {
elementRef.addEventListener('scroll', onScroll)
scrollListenerAttached = true
// 默认触发一次分页接口
await onReachBottomFn(moreQueryParams.value)
}
}
const clearListener = () => {
if (elementRef) {
elementRef.removeEventListener('scroll', onScroll)
}
}
const updateQuery = (newQuery) => {
moreQueryParams.value = newQuery
}
onUnmounted(() => {
clearListener()
})
return {
isReachBottom,
attachScrollListener,
updateQuery
}
}
export default useScrollBottom
使用:
const { isReachBottom, attachScrollListener, updateQuery } = useScrollBottom(getDataFn, 30)
onMounted(() => {
attachScrollListener(listRef.value)
})
const getDataFn = async () => {
pageNum.value++
loading.value = true
const res = await fn({
currentPage: pageNum.value,
pageSize: pageSize.value,
orderBoardModuleToDealType: orderBoardModuleToDealType.value
})
loading.value = false
if (res.data?.length) {
contentList.value = [...contentList.value, ...res.data]
}
return new Promise((c) => c(pageNum.value * pageSize.value >= Number(res?.data?.total)))
}

浙公网安备 33010602011771号