引子
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
在开发小程序时,我们时常要使用到上拉触底,但是在上拉触底事件中,除了使用onReachBottom()函数,我们还需要做节流处理,以防止频繁触发该事件导致频繁发起请求; 阅读本文大约需要 5min
场景
现在项目中有个需求是采用流水屏页面,让用户每次滑动屏幕触底时自动加载数据,从而实现无限加载;但是在滑动过程中时常会发生频繁发送请求,因此我们要让用户就算一直滑动到底部,也只让其每次滑动底部的只执行一次,从而达到节流的效果;
代码示例
我们先来看一下项目需求大概:
后端每次根据前端传递的页数返回数据,前端接收后实现拼接,再配合上拉触底实现无限滑动
功能代码如下:
页面初始数据
data: {
shopList: [], // 列表数据
page: 1, // 当前页
pageSize: 10, // 每页条数
total: 0, // 总页数
},
请求数据代码块
getShopList() {
wx.request({
url: 'www.xxx.com/api',
method: "GET",
data: {
_page: this.data.page, // 当前的页数
_limit: this.data.pageSize // 总页数
},
// 成功执行函数
success: ({ data: res, header }) => {
this.setData({
// 新数据拼接旧数据,采用es6展开运算符,就不多说了
shopList: [...this.data.shopList, ...res],
// 获取总页数 (其实不用每次都获取,因为是固定的)
total: header['X-Total-Count'] - 0
})
}
})
},
// 页面初始执行渲染
onLoad: function (options) { this.getShopList() },
上拉触底加载代码块
// .js 文件
onReachBottom() {
// 判断数据是否加载完毕
if (this.data.page * this.data.pageSize >= this.data.total) { return ... }
// 每次触底使页数 +1
this.setData({
page: this.data.page + 1
})
// 让其重新获取
this.getShopList();
}
从上面我们可以得知,刚刚进入页面会执行一次 getShopList() 请求,在每一次触底后也会再次加载数据请求,虽然说看上去挺完整的,但是每当我们在测试时频繁的往下滑就会发现,只触一下底居然能执行好几次数据请求,因此得通过下方节流阀来控制数据请求;
节流阀实现
节流阀的实现分为 3 步骤 : 定义开关变量 - 使用开关实现单独请求 - 判断是否为正在请求
首先在 data 中定义一个开关变量 isLoding:
data: {
...
isloading: false // 开关: 用于判断是否正在加载
},
其次在请求函数中配置 开 与 关,逻辑是执行加载的条件是isLoding 为 false ,表示现在没有加载;每当触发上拉触底时,使用 isLoding 为 true, 表示正在执行加载;
其中 wx.showLoading() 与 wx.hideLoding() 为加载样式,可根据自身按需使用
getShopList () {
// 节流阀 -- 执行加载
this.setData({
isLoding : true
})
// 加载请求时显示加载样式
wx.showLoading({
title: '加载中...',
})
wx.request({ ...
success: () => {... },
// complete :函数请求结束后才执行
complete: () => {
// 结束请求时关闭加载样式
wx.hideLoading()
// 节流阀 -- 放行加载
this.setData({
isLoding : false
})
}
})
},
到这里还不够,我们只是让其搭配开关加载,没有达到真正的节流;
因此还需在触发上拉触底时加上一句关键判断,修改后的代码为:
onReachBottom() {
if (this.data.page * this.data.pageSize >= this.data.total) { return ... }
// 判断如果正在加载就不执行上拉触底数据请求
if (this.data.isLoding) return;
this.setData({
page: this.data.page + 1
})
this.getShopList();
},
这种方式适用于多种场景,不止于小程序,这是一种编程思想 最后如果本文对于本文有疑惑,还请指导勘正 (●'◡'●)