微信小程序&移动端的触底分页&下拉刷新
-
首先需要定义一个变量用来表示当前数据获取的状态 eg: status:['nomore','more','loading','error'] // 设定status的初始值为more
-
其次书写获取列表数据的方法 a. 先修改status的值为loading,代表我们的请求正在加载中 b. 然后发请求获取数据,判断返回的数据长度 i. 如果长度大于0,说明请求的数据还有,此时有两种情况 1. 如果返回的数据长度小于我们发请求时的pageSize,则说明此时数据已经完全加载,没有更多的数据了,需要修改status为nomore 2. 如果返回的数据长度等于我们发请求时的pageSize,并不能说明下一页还有数据,只能说明这次发请求返回的数据满足所需要的数据条数,但下一页的数据是否还有我们不能判断,可以继续发送下一页的请求在来判断,需要修改status为more,然后将pageNumber++ 3. 在数据返回时,我们需要将列表展示的data进行赋值: 此时需要注意的是,如果是vue2,我们需要用this.list.push(result.data)来添加数据,因为vue2中对于响应式数组数据需要使用数组方法来修改,不能通过赋值来实现 如果是vue3,且是组合式API写法,可以直接list.value = [...list.value, ...result.data] 来添加数据 ii. 如果长度等于0,则说明请求的数据为空,则代表数据已经完全加载,没有更多的数据了,此时需要修改status为nomore iii. 如果走到了catch里面,则说明我们的请求出错了,此时就需要修改status为error
-
status状态判断
- 当status为nomore时,说明没有数据了,所以就不需要再发请求
- 当status为error时,说明请求发送失败了,也不需要在发请求
- 当status为loading时,也不要在多次发送请求。eg:用户一直进行触底的操作,如果为loading时继续发送请求,则会有多个返回,顺序无法确定,以及会造成数据的混乱等
小程序中:
- 我们可以使用onReachBottom函数,它会自动判断我们是否已经触底,然后当status为more时,我们在发请求获取下一页的数据
- 我们可以使用onPullRefresh函数,直接将pageNumber变为1,然后发送请求就可以了 移动端中(拿vant组件举例):
- vue3配合vant组件没有像小程序那样直接的触底函数,van-list组件有load方法,是进行数据加载的
- 我们可以采用类似小程序的方法,然后再load方法中,去进行status的判断然后再抓取数据,就能达到和小程序中相同的效果
- 当下拉刷新时,我们可以采用van-pull-refresh组件的refresh方法,将finished变为false,然后将数据清空,在将页码变为1,在抓取数据就可以了。
综上所述,我们在进行触底分页时,需要设置一个status用来判断是否继续获取分页的数据,然后通过数据返回的长度与pageSize比较来修改status的值,进而在触底时进行获取数据的控制
移动端代码:
<template>
<div>
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list
v-model:loading="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
:offset="100"
:immediate-check="false"
>
<van-cell v-for="item in list" :key="item" :title="item" />
</van-list>
</van-pull-refresh>
</div>
</template>
<script setup>
import { onMounted, reactive, ref } from 'vue';
const list = ref([])
const loading = ref(false)
const finished = ref(false)
const refreshing = ref(false);
const requestStatus = ref('more')
const searchParams = reactive({
page: 1,
page_size: 10
})
onMounted(() => {
initLoad()
})
const initLoad = async () => {
try {
requestStatus.value = 'loading'
loading.value = true
const res = await getMyLeaveForm(searchParams)
if(res) {
let detailData = JSON.parse(res)
if(detailData.result.length > 0) {
if(detailData.result.length < searchParams.page_size){
requestStatus.value = 'nomore'
finished.value = true
}else {
requestStatus.value = 'more'
searchParams.page++
}
list.value = [...list.value, ...detailData.result]
loading.value = false
refreshing.value = false
}else {
requestStatus.value = 'nomore'
finished.value = true
}
}
} catch (error) {
requestStatus.value = 'error'
}
}
const onLoad = () => {
requestStatus.value === 'more' && initLoad()
}
const onRefresh = () => {
// 清空列表数据
finished.value = false;
list.value = []
// 重新加载数据
// 将 loading 设置为 true,表示处于加载状态
loading.value = true;
searchParams.page = 1
initLoad();
};
</script>
小程序端代码:
import { findGoodList } from "../../../utils/api";
Page({
/**
* 页面的初始数据
*/
data: {
goodList: [], // 商品列表
page: 1, // 分页的页码
limit: 10, // 每页的个数
loadStatus: 'more', // more(可能还有) | nomore(后边一定没有了) | loading(正在加载) | error(加载错误)
category2Id: '', // 商品分类的二级id
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// console.log('options: ', options);
options.category2Id && this.setData({
category2Id: options.category2Id
})
this.getGoodList();
},
/* 获取goodList的功能函数 */
async getGoodList() {
try {
let { page, limit, goodList, category2Id } = this.data;
// 修改loadStatus状态
this.setData({
loadStatus: 'loading'
})
let result = await findGoodList({ page, limit, category2Id });
if (result.code === 200) {
let records = result.data.records;
if (records.length > 0) {
if (records.length === limit) { // 后边可能还有数据
this.setData({
loadStatus: 'more'
})
} else {
this.setData({
loadStatus: 'nomore'
})
}
goodList.push(...records);
this.setData({
goodList,
page: ++page
})
} else { // 当前获取的是空数组
this.setData({
loadStatus: 'nomore'
})
}
} else {
this.setData({
loadStatus: 'error'
})
}
} catch (error) {
console.log(error);
this.setData({
loadStatus: 'error'
})
}
},
/* 页面上拉触底的回调函数 */
onReachBottom() {
console.log('页面触底了。。。');
this.data.loadStatus === 'more' && this.getGoodList();
}
})
作为一个入行不久的前端开发,以上是小弟的一些见解,期待各位的补充,如果有什么说的不对的地方,也请指出,会及时的更正~ 感谢各位大佬