微信小程序:优雅处理分页功能
背景
在公司的项目中,分页功能十分常见,以前就是简单的复制粘贴,每次来回切换切面,还经常复制错位置或复制到其他页面去了,半天找不到原因(内心:#*! $%^&@ 1)。
核心思路
分页原理:
属性 page
来控制分页数,初始值为1;moreFlag
有更多数据的标志,初始值为true;pageSize
页面自行定义,可以默认设置为10
组件 原生scroll-view
或recycle-view
,但内容页面定制化(循环detailList
)
方法 bindscrolltolower
或 bindscrolltoUpper
调取接口获取更多数据,若结果集中的数据量小于pageSize时,moreFlag更新为false,界面激活“暂无更多”标识;bindrefresherrefresh
时刷新重置变量为初始值。
后端接口对接 一般接口都会用Promise异步封装,但一般页面中的请求和处理都各不相同,所以不能作为共同点
graph TD
getListChangeStatus初始化 --> getList加载数据 --> getRemoteList调接口输出处理好的结果集 --> getList合并结果集 --> 下拉刷新重置pulldownRefresh
混入
根据上面的分页原理,大都为逻辑处理,所以考虑使用类似Vue里的混入,而在小程序中有一个类似的语法:Behavior
Behavior
behaviors
是用于组件间代码共享的特性,类似于一些编程语言中的 “mixins” 或 “traits”。
每个 behavior
可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中,生命周期函数也会在对应时机被调用。 每个组件可以引用多个 behavior
,behavior
也可以引用其它 behavior
。
定义Behavior
和组件的配置参数差不多,点击查看详情
注意 即使运用在Page
里,方法也需放在methods
里;同时注意一下同名字段和生命周期的规则,如下图所示:
以 scroll-view 按照分页原理来定义分页的Behavior
module.exports = Behavior({
data: {
page: 1,
moreFlag: true,
detailList: [],
refreshFlag: false
},
methods: {
// 初始化
async getListChangeStatus() {
this.setData({
page: 1,
detailList: [],
moreFlag: true
})
await this.getList()
},
// 获取列表
async getList() {
if (!this.data.moreFlag) {
... // 可以增加处理,例如吐司等
return
}
let { detailList,fun } = await this.getRemoteList()
if (detailList) {
let detailListTem = this.data.detailList
if (this.data.page == 1) {
detailListTem = []
}
if (detailList.length < this.data.pageSize) {
//表示没有更多数据了
this.setData({
detailList: detailListTem.concat(detailList),
moreFlag: false
})
} else {
this.setData({
detailList: detailListTem.concat(detailList),
moreFlag: true,
page: this.data.page + 1
})
}
// 可能需要一些处理,例如获取容器的高度之类的,又或者scroll-int0-view对应id
if(fun && fun instanceof Function) fun()
}
},
// 到达底部
reachBottom() {
console.log('--reachBottom--')
this.getList()
},
// 下拉刷新重置
pullDownRefresh() {
this.setData({
page: 1,
hasMoreData: true,
detailList: []
})
this.getList()
setTimeout(() => {
this.setData({
refreshFlag: false
})
}, 500)
}
}
})
引入方法
在页面或组件中(如果页面多个需要分页的地方建议用组件)使用behaviors: [myBehavior]
import pagination from '../../behaviors/pagination.js'
Page({
data: {
pageSize: 10
},
behaviors: [pagination],
onShow() {
this.getListChangeStatus()
},
async getRemoteList() {
let { page, pageSize } = this.data
const returnObj = {}
const res = await XXX // 请求接口
... // 处理数据
returnObj.detailList = data
return returnObj
}
})
<scroll-view scroll-y refresher-enabled refresher-triggered="{{refreshFlag}}" bindrefresherrefresh="pullDownRefresh" bindscrolltolower="reachBottom" style="height:100%;">
scroll-view>
作者:HuaHua的世界
来源:juejin.cn/post/7267417634478719036
来源:juejin.cn/post/7267417634478719036