向上滚动加载数据
wenking 8/15/2024 通用组件
# 模版代码
<div @scroll="onScroll" ref="scrollTopLoadingDataRef" id="scroll-top-loading-data">
<div v-if="showLoading" class="loading">{{ loadingText }}</div>
<div class="box" :key="item" v-for="item in boxList">{{ item }}</div>
</div>
1
2
3
4
2
3
4
# 模拟网络请求
let idx = 0;
const getBoxes = () => {
return new Promise((resolve) => {
let result = []
setTimeout(() => {
// 模拟没有更多数据
if (idx > 10) {
resolve(result)
return
}
// 填充数据
for (let i = idx + 9; i >= idx; i--) {
result.push(i)
}
// 更新索引记录
idx = idx + 10
resolve(result)
}, 2000)
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 关键代码
const onScroll = async (e) => {
// 查找目标元素
let scrollTopLoadingDataRef = document.querySelector("#scroll-top-loading-data")
if (e.target.scrollTop === 0 && !showLoading) {
console.log("开始加载数据。。。")
// 记录当前滚动盒子高度
beforeScrollHeight = scrollTopLoadingDataRef.scrollHeight
// 开启加载提示
showLoading = true
try {
const result = await this.getBoxes()
console.log("result", result)
if (result.length === 0) {
loadingText = '没有更多数据了'
// 如果没有数据,不应该修改 scrollTop 属性,否则又会立即触发 onScroll事件,导致进入死循环
return
}
boxList.unshift(...result)
} catch (e) {
console.log(e)
} finally {
// 无论如何最总都会执行
showLoading = false
}
// 设置当前滚动盒子距离顶部偏移 = 当前总滚动盒子高度 - 未添加元素之前滚动盒子高度
scrollTopLoadingDataRef.scrollTop = scrollTopLoadingDataRef.scrollHeight - beforeScrollHeight
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29