在微信小程序上显示的内容列表,需要分页显示,向下滚动页面,页面到底了以后如果列表里面还有要显示的项目,就把下一页上的内容项目加载进来放到当前的页面上显示出来。这个就是无限页面加载功能。
思路
小程序的页面滚动到底部的时候,会触发一个 onReachBottom 方法,在这个方法里我们可以去实现加载下一页内容项目的功能。页面加载(onLoad)以后,向服务端请求得到第一页要显示的内容项目,通常在得到的响应里面,服务端会包含一些额外的信息,比如请求的列表一共有多少个项目,当前给我们的是哪些,当前的页码是什么,列表分成了多少页等等。利用这些信息,结合 onReachBottom 就可以实现无限加载功能了。
可以在小程序页面的数据(data)里面记录一下分页的状态,比如当前页(currentPage),一共有多少页(totalPages)。每次滚动到页面底部的时候,就重新设置一下 currentPage 的值,让它加上 1 ,然后去载入下一页的内容,得到数据以后放在当前页面的列表数据里面,重新设置页面的数据会触发页面重新渲染。
实践
下面我们用 WordPress 的文章列表接口做个演示。
数据
页面上的数据大概像这样:
data: { entities: [], totalPages: 0, currentPage: 1, isLoading: true, },
entities 是要表示的内容列表项目,totalPages 表示一共有多少页,currentPage 表示当前加入的页码是哪个。isLoading 表示加载的状态。
初始数据
在页面的 onLoad 这个生命周期方法里,可以使用 wx.request 去请求页面的初始数据,得到了数据以后,就把数据放到页面上用。
onLoad () { wx.request({ url: `${ API_BASE }/${ API_ROUTE }`, success: (response) => { const entities = response.data this.setData({ entities, isLoading: false, totalPages: response.header['x-wp-totalpages'], currentPage: 1, }) } }) },
WordPress 的列表接口上,表示一共有多少页的信息是在一个 header 里面,response.header['x-wp-totalpages']。其它的后端服务接口应该有类似的信息。
无限加载
页面滚动到底儿会触发执行 onReachBottom,在页面上添加一个这样的方法,执行它的时候让它去请求列表里面的下一页内容,再把得到的内容合并到页面数据里面的列表数据里。
onReachBottom () { let { currentPage, totalPages, isLoading } = this.data if (currentPage >= totalPages || isLoading) { return } this.setData({ isLoading: true }) currentPage = currentPage + 1 wx.request({ url: `${ API_BASE }/${ API_ROUTE }?page=${ currentPage }`, success: (response) => { console.log(response) const entities = [...this.data.entities, ...response.data] this.setData({ entities, currentPage, isLoading: false, totalPages: response.header['x-wp-totalpages'], }) } }) } })
再分解一下。在方法里,先把 currentPage,totalPages,isLoading 这些数据从页面数据里拿出来用一下:
let { currentPage, totalPages, isLoading } = this.data
然后我们检查一下,看看当前页面是不是大于等于总共的页面,或者如果当前页面是加载状态,我们直接 return,就是什么都不做:
if (currentPage >= totalPages || isLoading) { return }
接着设置了页面的加载状态,然后让当前页码加上 1 :
this.setData({ isLoading: true }) currentPage = currentPage + 1
接着再用 wx.request 去请求下一页上的内容项目:
wx.request({ url: `${ API_BASE }/${ API_ROUTE }?page=${ currentPage }`, success: (response) => { console.log(response) const entities = [...this.data.entities, ...response.data] this.setData({ entities, currentPage, isLoading: false, totalPages: response.header['x-wp-totalpages'], }) } })
在请求的接口地址里面,添加了一个 page 参数,它可以设置具体要得到哪一页上的数据,它的值我们用 currentPage 来表示。成功得到了数据以后,我们把新的列表数据跟当前在页面上显示的列表数据合并到一块儿了。这里用了 JavaScript 的 Spread 操作符(...)。用 setData 方法重新设置页面上的数据,会让页面视图重新显示。
微信小程序
评论
Setting data field "total" to undefined is invalid.
Setting data field "totalPages" to undefined is invalid.
6 年 5 个月 以前
说变量里没值,你可以在控制台上输出一些东西,调试一下看看,为啥没有值。
6 年 5 个月 以前
报错是为什么
6 年 5 个月 以前
文章列表的第一屏缩略图是有的,下拉的时候后面的缩略图不显示,然后报的这个错
6 年 5 个月 以前
嗯,你调试下看看,在控制台上输出你要在页面上显示的数据,看看是不是少了一些东西。
6 年 5 个月 以前
合并展示是只渲染新的数据还是把两个数组合并起来然后展示这个大的数组,我现在遇到一个问题就是无限向下拉加载时间越来越大,我是用concat合并的,但是换成你这个...就会好很多,求解
5 年 3 天 以前
把新请求回来的数据放到现有的数据里。
5 年 3 天 以前
那就不是合并喽?
5 年 3 天 以前
但感觉还是合并
5 年 3 天 以前
我加你微信了,也加群了,求通过
5 年 3 天 以前