分页加载时怎么避免重复请求和数据错乱?
我用 Vue 做了个列表,滚动到底部就加载下一页,但有时候快速滚动会触发多次请求,导致数据重复或者顺序错乱。试过加 loading 锁,但好像没完全解决问题。
这是我的加载逻辑:
<template>
<div @scroll="handleScroll" style="height: 400px; overflow-y: auto">
<div v-for="item in list" :key="item.id">{{ item.name }}</div>
</div>
</template>
<script>
export default {
methods: {
async handleScroll() {
if (this.loading) return;
this.loading = true;
const res = await fetch(/api/items?page=${this.page++});
this.list.push(...res.data);
this.loading = false;
}
}
}
</script>
首先,把 loading 变量改成更清晰的状态机,比如 idle/loading/completed/error。然后用防抖来限制频繁触发。
另外,你可能需要检查当前页数和总页数,避免重复请求已经获取过的数据。
这里给你改进后的代码逻辑:
这个版本加入了状态管理和防抖,调试看看应该能解决你的问题。记得测试快速滚动的情况。这种异步操作的场景最容易出问题,多测几个边界情况总是好的。
1. 加个防抖,避免滚动事件触发太频繁:
2. 要做页码校验,防止并发请求导致page自增混乱:
3. 安全提醒:别忘了加错误处理,网络请求可能会失败。建议把loading状态放在finally里:
另外建议用IntersectionObserver替代scroll事件监听,性能更好也更精确。不过要看你项目浏览器兼容性要求。