onReachBottom未触发最常见原因是滚动容器非page根节点,如使用scroll-view导致局部滚动;应改用scroll-view的@scrolltolower事件并设固定height和scroll-y。

uni-app 的 onReachBottom 为什么没触发?
最常见原因是页面滚动容器不是 <page> 根节点,比如用了 <scroll-view> 或自定义高度的 <view>。uni-app 的 onReachBottom 默认监听的是整个页面(即 page)的滚动触底,一旦你用 <scroll-view> 包裹列表,它就变成局部滚动,onReachBottom 就失效了。
解决办法分两种:
- 不用
<scroll-view>,让列表直接撑满页面,确保page可滚动(需在pages.json中关闭原生导航栏或留出足够内容高度) - 改用
<scroll-view>的@scrolltolower事件,但必须显式设置height和scroll-y,否则无法触发
注意:scroll-view 的 height 必须是固定数值(如 80vh 或具体 px),百分比在某些平台(尤其是微信小程序)可能不生效。
onReachBottom 触发后如何防重复请求?
用户快速上拉或网络慢时,容易连续触发多次,导致重复加载相同页码数据。不能只靠 loading 状态变量控制,因为异步请求未返回前状态可能已重置。
推荐做法:
- 加一个
isLoadMore标志位,在请求开始时设为true,成功/失败后才设为false - 每次请求前先判断
if (this.isLoadMore || this.hasMore === false) return - 后端返回数据时,明确提供
has_more: true/false字段,而不是仅靠数组长度判断是否还有下一页
示例关键逻辑:
onReachBottom() {
if (this.isLoadMore || !this.hasMore) return;
this.isLoadMore = true;
uni.request({
url: '/api/list',
data: { page: this.page + 1 },
success: (res) => {
this.page++;
this.list.push(...res.data.list);
this.hasMore = res.data.has_more;
},
complete: () => {
this.isLoadMore = false;
}
});
}微信小程序里 scroll-view 的 @scrolltolower 不触发?
这是高频兼容性问题:微信小程序要求 scroll-view 必须有明确的 height,且内部内容总高度必须 > height,否则不会出现滚动条,自然也不会触发 @scrolltolower。
实操要点:
- 用
vh单位比%更可靠,例如height: calc(100vh - 100px)(减去顶部导航和 tabbar 高度) - 在
mounted或onReady中用uni.createSelectorQuery()动态获取容器高度并赋值,避免硬编码 - 确保子元素(如
<view v-for>)没有position: absolute或flex: none导致高度塌陷
错误写法:<scroll-view @scrolltolower="loadMore"></scroll-view>(缺 height、scroll-y)
正确写法:<scroll-view scroll-y="true" :style="{height: containerHeight + 'px'}" @scrolltolower="loadMore">
下拉刷新和上拉加载共存时的冲突点
启用 enablePullDownRefresh 后,部分安卓机或旧版微信开发者工具中,onReachBottom 会在下拉刷新完成后的首次滚动时误触发一次——本质是刷新后页面 scrollTop 被重置,触发了“触底”判定。
规避方式:
- 在
onPullDownRefresh里手动重置分页状态:this.page = 1; this.list = []; this.hasMore = true; - 在
onReachBottom开头加判断:if (this.page === 1) return;(因为第一页已由下拉刷新加载完) - 不要在
onPullDownRefresh里调用uni.stopPullDownRefresh()后立刻触发滚动,可加setTimeout(() => {}, 100)微调时机
另外,uni.startPullDownRefresh() 在某些平台(如 H5)不支持自动滚动到顶,需手动 this.$nextTick(() => uni.pageScrollTo({scrollTop: 0})) 配合。
真正麻烦的不是写法,而是不同平台对“滚动容器”和“触底判定”的实现差异——测试必须覆盖微信小程序、App、H5 三端,尤其注意真机调试时的滚动行为。


















