微信小程序:优雅处理分页功能
背景
在公司的项目中,分页功能十分常见,以前就是简单的复制粘贴,每次来回切换切面,还经常复制错位置或复制到其他页面去了,半天找不到原因(内心:#*! $%^&@ 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