小程序上拉加载更多应使用原生页面级回调onreachbottom而非scroll事件或scroll-view的bindscrolltolower,因其稳定可靠、不依赖高度计算、不受嵌套影响;需配置onreachbottomdistance、确保可滚动内容,并在逻辑中正确处理数据追加、状态控制与hasmore守卫。

小程序的上拉加载更多不是靠监听页面滚动位置手动计算,而是直接用框架提供的生命周期回调 onReachBottom —— 这是唯一可靠、无需 hack 的方式。
为什么不能监听 scroll 事件做上拉加载
小程序的 scroll-view 组件虽然支持 bindscrolltolower,但它的触发不稳定:内容高度不足一屏时根本不会触发;手速慢或滚动惯性不足也会漏掉;且需额外维护 scrollTop 和容器高度,容易误判。而 onReachBottom 是页面级原生回调,只要用户滑到底部(无论怎么滑),就会稳定触发。
- 它不依赖 DOM 高度计算,也不受
scroll-view嵌套层级影响 - 不需要手动加
scroll-y、lower-threshold等冗余配置 - 即使列表只有一条数据,只要用户真滑到了页面底部,它仍会调用
onReachBottom 必须配合的三项配置
这个函数默认是关闭的,必须显式启用,否则永远不执行:
- 在当前页面的
json文件中加"onReachBottomDistance": 50(单位 px,表示距离底部 50px 时触发,别设为 0) - 确保页面 WXML 根容器里有可滚动内容(比如
<scroll-view></scroll-view>或长文本/图片堆叠),否则页面本身无法滚动,自然触不到底 - 不要在
onReachBottom里直接写异步请求却不控制状态 —— 比如没设this.data.isLoading = true,用户连点两次就会发两个请求
数据拼接时最常踩的坑
上拉加载的本质是「追加」,不是「替换」。错误做法是 this.setData({ list: res.data }),这会把第一页数据也冲掉。
- 首次加载用
this.setData({ list: res.data }) - 后续上拉必须用
this.setData({ list: this.data.list.concat(res.data) })或[...this.data.list, ...res.data] - 后端返回的
has_more字段要存到data里,下次进onReachBottom先判断:if (!this.data.hasMore) return - 请求失败时别忘了恢复
isLoading状态,否则按钮一直卡死
没有更多数据时的正确收尾动作
后端返回 has_more: false 后,仅禁用按钮或隐藏“加载更多”提示是不够的。小程序会继续尝试触发 onReachBottom,除非你主动告诉它“停手”:
- 调用
wx.stopPullDownRefresh()不起作用 —— 这是给下拉刷新用的 - 正确做法是设置
this.setData({ hasMore: false }),并在onReachBottom开头加守卫判断 - 如果想显示“暂无更多”,在 WXML 里用
<view wx:if="{{!hasMore}}">没有更多了</view>即可 - 别在
onReachBottom末尾调me.resetload()或类似 iScroll 的方法 —— 小程序没有这个 API,写了就报错
真正麻烦的从来不是“怎么触发”,而是“怎么稳住状态”:页码是否同步、loading 是否可控、空响应是否被当成错误、网络乱序是否覆盖数据 —— 这些细节不盯紧,上线后用户猛划几下,列表就乱序或白屏。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











