小程序要下拉刷新,有两种方式:
- 整个页面刷新
- 局部刷新
- 整个页面刷新
整体刷新首先需要再页面配置文件(json)中添加配置:
"enablePullDownRefresh": true
添加配置后页面可以下拉,然后再js文件onPullDownRefresh
中编写下拉刷新逻辑代码。注:处理完后需调用wx.stopPullDownRefresh()
结束下拉刷新,否则真机上页面下拉后不会回到原来的位置。
- 局部刷新
对于有些页面,如下图:
顶部是切换的导航条剩下的是列表,刷新的时候不需要带着导航一起下拉刷新。小程序提供了一个组件:scroll-view
。我们只需要使用scroll-view
将列表数据包裹起来就可以了。
refresher-enabled="true"
开启下拉刷新refresher-triggered="{{refresherTrigger}}"
控制下拉刷新显示,在数据请求结束后应将refresherTrigger
设置为false
bindrefresherrefresh="pullDownRefresh"
在js文件pullDownRefresh
函数中处理下拉刷新逻辑
对于局部刷新,当页面数据较少的时候,我们会遇到一个问题:
可以看到高度存在问题,scroll-view官方文档中有说:
可滚动视图区域。使用竖向滚动时,需要给scroll-view一个固定高度,通过 WXSS 设置 height。组件属性的长度单位默认为px,2.4.0起支持传入单位(rpx/px)。
- 失败尝试
对于列表,高度是未知的。在WXML
中写样式:style="height: 100vh;"
尝试,对于数据少的问题解决了,但是数据多有分页的列表又出现了问题,无法加载下一页数据。那么,如果数据加载完后我们能知道页面有多少数据,就可以知道该用哪一个高度了。
解决办法:
使用自定义事件,当page等于1
时,在组件中根据数据多少判断应使用100vh
还是100%
并返回单位:
this.triggerEvent('initHeight', {unit: data.length >= 10 ? '%' : 'vh'})
这个方案显示和下拉会出现问题。
- 最终方案
- 在页面配置文件中添加禁用页面滚动。如果这里不禁用滚动是属于页面的,而非
scroll-view
的。
"disableScroll": true
- 给
scroll-view
加上一个id属性,class
等也行,完整如下:
<scroll-view id="scrollList" refresher-enabled="true" scroll-y="true" enable-back-to-top="true" refresher-triggered="{{refresherTrigger}}" bindscrolltolower="reachBottom" bindrefresherrefresh="pulldownRefresh" style="height: {{scrollHeight}};">
// 其他页面代码...
</scroll-view>
- 使用
this.createSelectorQuery()
查询scroll-view
节点,用屏幕高度减去scroll-view
距离顶部的高度,得到该元素所占高度。这样scroll-view
刚好铺满页面。如果你的scroll-view
只是在页面中间的一部分,那还需要减去底部距离。
const systemInfo = wx.getSystemInfoSync();
const query = this.createSelectorQuery();
query.select('#scrollList').boundingClientRect(rect => {
if(rect !== null) {
this.setData({
scrollHeight: `${systemInfo.windowHeight - rect.top}px`
})
}
}).exec()
实际项目中,由于很多页面都会用到这段代码,可以将其封装到behavior里面,其他页面直接调用便可。
module.exports = Behavior({
data: {
scrollHeight: '100vh'
},
methods: {
initScrollHeight: function(selector = '#dataList') {
const systemInfo = wx.getSystemInfoSync();
const query = wx.createSelectorQuery().in(this);
query.select(selector).boundingClientRect(rect => {
if(rect !== null) {
this.setData({
scrollHeight: `${systemInfo.windowHeight - rect.top}px`
})
}
}).exec()
}
}
})
注意:在真机上,部分机型有些列表最后一条数据可能被tabbar遮挡,这样的单独处理,在样式中添加一个距离底部的边距即可。