wechat-miniprogram-examples之滚动加载:scroll-view实现上拉加载更多与下拉刷新的5个技巧
【免费下载链接】wechat-miniprogram-examplesWeChat mini program examples. 微信小程序示例项目地址: https://gitcode.com/gh_mirrors/we/wechat-miniprogram-examples
在微信小程序开发中,scroll-view 上拉加载更多与下拉刷新几乎是每个列表页的标配功能。很多新手在实现时总会遇到"滚动不触发""重复请求""刷新失效"等经典问题。而开源项目wechat-miniprogram-examples(微信小程序示例)中的豆瓣图书、知乎日报两个案例,恰好给出了两套风格迥异但都非常经典的滚动加载实现方案,非常适合新手对照学习。本文基于该项目源码,为你拆解 scroll-view 实现上拉加载更多与下拉刷新的 5 个实用技巧。
先认识项目:两个现成的滚动加载示例
wechat-miniprogram-examples 一共包含三个小程序示例:豆瓣图书、知乎日报、事项助手。其中滚动加载相关的核心代码集中在两个目录:
- 豆瓣图书(上拉加载更多):
DouBanBookApp/pages/index/ - 知乎日报(下拉刷新 + 加载更多):
ZhiHuDaily/pages/index/
想亲自运行调试,可以克隆仓库后分别用微信开发者工具打开对应目录:
git clone https://gitcode.com/gh_mirrors/we/wechat-miniprogram-examples小提示:项目内每个小程序都没有配置 appid,运行前需要在开发者工具中为项目分配一个 appid,否则真机预览可能受限。
技巧1:给 scroll-view 一个固定高度,让 bindscrolltolower 真正触发 ⚙️
上拉加载更多的原理是监听滚动到底部的事件,但很多新手发现bindscrolltolower怎么都不触发,原因往往是scroll-view 没有固定高度。scroll-view 只有在自身可滚动(内容超过可视高度)时,滚动到底事件才会生效。
豆瓣图书示例的做法非常清晰,在DouBanBookApp/pages/index/index.wxml中:
<scroll-view scroll-y="true" style="height:{{scrollHeight}}px" bindscrolltolower="scrollLowerEvent">高度scrollHeight不是写死的,而是在页面onShow时通过wx.getSystemInfo动态获取屏幕高度计算得出(见技巧5)。触底后由scrollLowerEvent负责加载下一页数据,核心判断只有一行:
!this.data.loadingMore && requestData.call(this);技巧2:用 loadingMore 标志位防抖,避免上拉加载重复请求 🛡️
快速滑动列表时,bindscrolltolower可能被连续触发多次,如果每次都发请求,不仅浪费流量,还会造成数据错乱。解决方案就是"加载中标志位 + 短路判断"。
在DouBanBookApp/pages/index/index.js中,数据里维护了一个loadingMore字段:
- 请求发起前:
setData({ loadingMore: true }) - 请求成功/失败后:
setData({ loadingMore: false }) - 触发事件时:
!this.data.loadingMore && requestData.call(this)
这个"防抖"模式虽然简单,却是滚动加载中最重要的一道保险,强烈建议每个列表页都加上。
技巧3:分页参数与数据拼接:pageIndex + concat 的正确姿势 📄
上拉加载的核心是"追加数据而不是覆盖数据"。豆瓣图书示例用两个字段管理分页:
pageIndex:当前页码,作为请求的start参数传给接口pageData:已加载的图书数组
每次请求成功后,用concat把新数据追加到旧数据后面,再递增页码:
pageData: this.data.pageData.concat(data.books), pageIndex: start + 1,知乎日报的加载更多则走"时间线"思路,用日期向前翻页(Api.getBeforeNews(dateStr)),同样用concat拼接每日新闻。两种分页策略虽不同,但追加式数据管理的思路完全一致。
技巧4:页面级下拉刷新:enablePullDownRefresh + onPullDownRefresh 🔄
滚动加载的另一半是下拉刷新。知乎日报采用的是页面级方案,只需两步:
第一步,在页面配置文件ZhiHuDaily/pages/index/index.json中开启开关:
{ "enablePullDownRefresh": true }第二步,在ZhiHuDaily/pages/index/index.js中监听下拉事件,重新拉取最新数据:
onPullDownRefresh() { this.onReady(); },由于onReady里已经封装了完整的"请求今日热文 + 轮播图"逻辑,下拉刷新直接复用它即可,代码非常简洁。
扩展知识:如果你用的是 scroll-view 内部滚动(而非整页滚动),也可以使用它自带的
refresher-enabled属性 +bindrefresherrefresh事件实现组件级下拉刷新,两种方式按页面结构取舍。
技巧5:动态计算 scroll-view 高度,适配不同机型 📱
scroll-view 需要固定高度,但不同手机屏幕高度差异很大,写死高度必然出问题。豆瓣图书示例用wx.getSystemInfo动态计算,堪称教科书写法:
wx.getSystemInfo({ success: (res) => { this.setData({ scrollHeight: res.windowHeight - (100 * res.windowWidth / 750) }); } })代码中100是顶部搜索框的 rpx 高度,通过rpx转px公式(rpx值 × 屏幕宽度 / 750)换算成像素后从窗口高度中减去,剩余部分正好是列表的滚动区域。这也是项目里唯一需要适配计算的技巧,学会了它,你的列表页在任何机型上都能完美贴合屏幕。
常见坑位清单:滚动加载避雷指南 🚧
| 问题现象 | 根本原因 | 解决方向 |
|---|---|---|
| bindscrolltolower 不触发 | scroll-view 无固定高度或内容不满一屏 | 动态计算高度,保证内容可滚动 |
| 快速滑动导致数据重复 | 触底事件连续触发 | loadingMore 标志位防抖 |
| 下拉刷新没反应 | 未开启 enablePullDownRefresh | 页面 json 中开启开关 |
| 列表数据被覆盖 | 直接赋值而非追加 | 使用 concat 拼接分页数据 |
| 真机预览异常 | 未配置 appid | 为项目分配 appid |
小结:跟着示例项目一次学会滚动加载 ✅
回顾 wechat-miniprogram-examples 教给我们的 5 个技巧:固定 scroll-view 高度、loadingMore 防抖、pageIndex 分页管理、页面级下拉刷新、动态计算高度适配机型。这些模式不仅适用于本项目,更是所有微信小程序列表页的通用套路。
想深入研读源码?推荐重点阅读这两个文件:
DouBanBookApp/pages/index/index.js—— 上拉加载更多 + 防抖 + 分页的完整实现ZhiHuDaily/pages/index/index.js与index.json—— 下拉刷新 + 按日期加载更多的实现
对照源码亲手跑一遍,相信你很快就能在自己的小程序中写出丝滑的滚动加载体验!
【免费下载链接】wechat-miniprogram-examplesWeChat mini program examples. 微信小程序示例项目地址: https://gitcode.com/gh_mirrors/we/wechat-miniprogram-examples
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考