触底加载效果
实现思路
触底加载更多的细节:
- 触底: 监测触底事件在触底之后执行一系列动作
- 加载数据: 在触底后需要向服务器请求数据,如果已经请求到了所有数据,应该不再发送请求。
- 加载状态: 请求数据的等待时间,需要更新状态为加载中,数据渲染完成后取消该状态的显示
- 数据渲染: 将请求到的数据显示在视图中
- 没有更多数据的提示
功能实现
1、数据结构
数据格式来源[风袖API文档](https://course.talelin.com/lin/sleeve/3 API:Banner.html)
{
"total":1,
"count":10,
"page":0,
"total_page":1,
"items":[
{
"id":8,
"title":"ins复古翠绿NoteBook",
"subtitle":"林白默默的掏出小本本,将她说的话一次不漏的记了下来。",
"img":"",
"for_theme_img":"",
"price":"29.99",
"discount_price":"27.8",
"description":null,
"tags":"林白推荐",
"sketch_spec_id":"1",
"max_purchase_quantity":null,
"min_purchase_quantity":null
}
]
}
2、产品的业务逻辑
//model/product.js
class product{
static goods=[{
id: 'P001',
image: '/image/图灵.jpg',
title: '长款系带风衣',
describe: '柔软顺滑、上身挺括显瘦。',
price: '888',
delPrice: '666'
}, //只留一个做展示
];
constructor() {
this.total=product.goods.length
}
async getProductList({count=5,page=1}){
this.count=count;
this.page=page;
this.total_page=Math.ceil(this.total/this.count);
const start=(this.page-1)*this.count;
const end=this.count*this.page;
this.items=product.goods.slice(start,end);
return new Promise(resolve => {
resolve(this.getDataTemplate())
})
}
getDataTemplate(){
return{
total:this.total,
count:this.count,
total_page:this.total_page,
page:this.page,
items:this.items
}
}
}
export {
product
}
其中 getDataTemplate()
对传入的数据进行格式上的封装,getProductList()
方法则是实现分页的逻辑并将结果返回为一个Promise
对象。
3、加载数据的确定
data: {
loadingEnd: false, // 是否loading完
loading: false, // loading的状态
products: [], // 展示的数据
productModel: null, // Products类创建的对象模型
currentPage: 1, // 当请求页的设置
pageCount: 5, // 每页请求数据的数量
}
4、初始第一页数据的加载
async onLoad(options) {
const productModel = new product();
const productList = await productModel.getProductList({
count: this.data.count,
page: this.data.currentPage
});
this.setData({
productModel,
products: productList
});
console.log(this.data.products);
this.renderWaterFlow();
},
renderWaterFlow() {
wx.lin.renderWaterFlow(this.data.products.items, false, () => {
console.log('渲染成功')
})
},
- 进入页面在没有触发触底事件时,第一页的数据进行正常的显示。所以在
onLoad
生命周期中进行。 - 这里创建了
product
类的实例productModel
方便后续向业务模型发送请求获取数据。紧接着调用该实例的getPorductList
方法,并传入请求页与每页显示数据条数获取第一页的产品数据,并将其更新到data中,进行数据的接受。 - 最后调用
lin-ui
提供的瀑布流组件进行数据的渲染。
###5、触底加载更多数据
onReachBottom: function() {
if (this.data.currentPage >= this.data.productModel.total_page) {
this.setData({
loadingEnd: true,
loading: false,
});
} else {
this.setData({
loading: true,
currentPage: this.data.currentPage + 1,
});
setTimeout(() => {
this.getPageProductList()
}, 2000)
}
},
async getPageProductList() {
const products = await this.data.productModel.getProductList({
count: this.data.pageCount,
page: this.data.currentPage
});
this.setData({
products,
});
this.renderWaterFlow();
},
onReachBottom
是小程序提供的触底事件处理方法,我们可以将触底后需要做的操作放在此函数中运行。
首先判断了当前展示的数据是不是最后一页的数据:
- 如果是的话就不再进行数据的请求,并将loading组件显示出来,loading状态设为false,loadingEnd设为true,进行
没有更多数据
提示的相关展示。 - 如果当前展示的数据没有到最后一页,则应请求下一页数据,并将loading组件加载出来,loading状态为加载状态。这里使用setTimeout模拟了发送和接收请求这段等待的时间。
getPorductList
方法里对(模拟的)后端进行了请求并做了数据设置,之后调用renderWaterFlow
进行瀑布流的展示,在lin-ui
瀑布流函数的回调中,同时也适用lin-ui
提供的页底提示进行加载信息的提升。
注:使用组建实现页底提示可以使开发的过程变的高效和易用
6、组建的引用
{
"usingComponents": {
"l-demo": "/components/l-demo/index",
"water-flow": "/miniprogram_npm/lin-ui/water-flow/index",
"l-loadmore": "/miniprogram_npm/lin-ui/loadmore/index"
}
}