60px 预加载:Vue无限滚动在仿抖音项目中的实现拆解
【免费下载链接】douyinVue3 + Pinia 仿抖音,Vue 在移动端的最佳实践 . Imitate TikTok ,Vue Best practices on Mobile项目地址: https://gitcode.com/GitHub_Trending/do/douyin
给长列表做分页时,“加载下一页”按钮常带来两个问题:页面跳动、滚动位置丢失。开源项目 douyin(Vue3 + Pinia 仿抖音)用一套 Vue无限滚动列表组件把这些问题解决掉了:信息流滚动接近底部就自动拉取下一页,全程不需要用户手动翻页。
这套滚动列表解决什么问题
douyin 是一个完整的移动端短视频应用,覆盖首页视频流、社区瀑布流、商城商品列表等模块。凡是“往下刷还有更多”的页面,底层都复用同一个 ScrollList 组件:把数据请求函数交给它,分页号维护、预加载触发、加载提示、“没有更多了”的展示全部在组件内部完成,页面只写渲染逻辑,不维护任何分页状态。
先跑通:把它接进你自己的页面
先把仓库拉下来跑一遍:git clone https://gitcode.com/GitHub_Trending/do/douyin
接进页面只需要一个组件标签,api属性传请求函数,插槽拿到已合并好的完整列表:
<ScrollList :api="recommendedShop"> <template #default="{ list }"> <div v-for="item in list" :key="item.id"> <img :src="item.cover" /> <span>{{ item.name }}</span> </div> </template> </ScrollList>对api的约定:入参是{ pageNo, pageSize }(pageSize 默认 10),返回{ success, data: { list, total } }。另外两个状态不用管:列表为空时自动显示全屏加载动画(fullLoading),list.length追上total时自动出现“暂时没有更多了”的提示。页面侧不需要再写任何分页代码。
60px 预加载是怎么触发的
结论:滚动预加载的判定只在底层 Scroll 容器 里做一次,距离底部不足 60px 就发出pulldown事件:
if (this.$attrs.onPulldown) { if (this.wrapper.scrollHeight - this.wrapper.clientHeight < this.wrapper.scrollTop + 60) { this.$emit('pulldown') } }效果:网络请求比用户滚到底提前了 60px 的距离,多数情况下数据已经返回,列表底部不会出现空白段。阈值 60px 就是“提前量”,嫌激进可以调小,怕来不及就调大。
加载锁如何挡住重复请求
结论:state.loading就是一个布尔锁,请求未结束前,任何第二次触发都直接 return:
function loadData() { if (state.loading) return state.pageNo++ getData() }效果:用户快速连刷时同一时刻只有一个请求在途,不会出现页码跳变或数据乱序。拿到新数据后用state.list.concat(res.data.list)增量拼接,而不是整体替换数组,已有列表项不会重新渲染。
下拉刷新组件与滚动记忆
Scroll 容器还监听 touchmove,当 scrollTop 为 0 且手指继续下移时,按distance - 40计算位移并以 10px 封顶,松手后触发refresh事件,页面监听它执行getData(true)重置页码重新拉取。滚动位置则靠 useScroll 在 keep-alive 的激活/停用时存取scrollTop,切走再切回不丢位置。
哪些页面在复用这套无限滚动实现
- LongVideo.vue:首页推荐长视频流,
api传recommendedLongVideo; - Community.vue:社区壁纸瀑布流,ScrollList 内嵌 WaterfallList 渲染卡片,下图就是信息流里的真实内容数据;
- Shop.vue 与 GoodsDetail.vue:商城商品列表和详情页“相关推荐”用的是同一个组件、同一个
recommendedShop接口。
还能往哪优化
- 虚拟滚动:目前列表项全部留在 DOM 里,条目上千后可改为只渲染可视区域、回收屏外节点,内存和重绘都能降一个量级。
- 错误重试:请求失败当前只弹“查询失败”提示,可在底部提示位加“点击重试”,并把失败的
pageNo回退 1 再发请求。
一套可复用的 Vue无限滚动实现:60px 预加载、加载锁、增量拼接。git clone https://gitcode.com/GitHub_Trending/do/douyin
【免费下载链接】douyinVue3 + Pinia 仿抖音,Vue 在移动端的最佳实践 . Imitate TikTok ,Vue Best practices on Mobile项目地址: https://gitcode.com/GitHub_Trending/do/douyin
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考