1.背景:分页是处理大数据量的一种常见方式,一般有页码分页、滚动分页的实现方式,表格页面分页非常常见,下面是一个列表或者表格的滚动分页。
2.话不多说,上代码:
(1)解题思路:首先,我采用了 element plus 上的v-infinite-scroll 属性 (无限滚动),在滚动时请求分页接口来获取数据;其次,每次请求后的数据都要拼接起来,最后,处理每次滚动都只请求一次接口 ,使用了nextTick(提高性能,减少不必要的计算和渲染,确保DOM更新完成后执行)
页面代码
<div
ref="scrollContainer"
class="container"
id="Content"
v-infinite-scroll="handleScroll"
>
<el-row>
<el-col
v-for="(item, index) in allChartList"
class="pb-10 pr-4"
:key="index"
>
<div class="chart-card">
<span>{{ item.tagName }}</span>
<span>{{ item.tagValue }}{{ item.unitName }}</span>
...
</div>
</el-col>
<p v-if="loading">Loading...</p>
</el-row>
<script setup lang="ts">
import { ref, computed, nextTick } from "vue";
const allChartList = ref<any>([]);
const loading = ref<boolean>(false);
const pageSize = ref<number>(16);
const pageNo = ref<number>(1);
const totals = ref<number>(0);
const totalPage = computed(() => Math.ceil(totals.value / pageSize.value)); // 计算出你的页码 防止无限滚动
const getData = async () => {
try {
const result:any = await 自己的API({
pageSize: pageSize.value,
pageNo: pageNo.value,
});
if (result.code === "0") {
if (result.data) {
totals.value = result.data.total;
const newData = result.data.list || []
allChartList.value = [...allChartList.value, ...newData];
}
} else {
ElMessage.error(result.msg || "查询失败");
}
} catch (error) {
loading.value = false;
}
};
// 处理滚动事件
const handleScroll = () => {
const scrollTop =
document.documentElement.scrollTop || document.body.scrollTop;
const clientHeight = document.documentElement.clientHeight;
const scrollHeight = document.documentElement.scrollHeight;
if (
scrollTop + clientHeight >= scrollHeight -10 &&
pageNo.value < totalPage.value
) { // 这里 需要把当前页面与我们数据的最大页码做比较 避免无限滚动
loading.value = true;
nextTick(() => { // 这一步重要!!它可以减少不必要的请求与渲染,确保请求的顺序,否则你滑动时可能一次性会请求好几次API这样数据就容易错乱
pageNo.value += 1;
getData();
loading.value = false;
});
} else {
loading.value = false;
}
};
</script>
效果如图:
20240820-142332