说明
示例以 elementui plus2.9.0+ 和 vue3的代码,主要用于滚动加载,分页加载的数据也可以使用这个数据,也就是把数据分割了。代码可能存在某些误差,去掉了不用的东西,有些代码简化了写,分页已被注释,需要的可以自行选择。
common.js
import { isRef, unref } from "vue";
/**
* 集合排序(没用,需要的可以使用)
* 使用参考:tableData.value?.sort(listSort(['jobno','jobn'],['asc','asc']));
*/
export const listSort = (props, orders = [])=>{
return (a, b) => {
for (let i = 0; i < props.length; i++) {
const prop = props[i];
const order = orders[i] || 'asc';
// 处理null
if (a[prop] == null) return 1;
if (b[prop] == null) return -1;
// 比较属性值
let compareResult = null;
if (typeof a[prop] === 'string') {
compareResult = a[prop].localeCompare(b[prop]);
} else {
compareResult = a[prop] - b[prop];
}
// 根据排序方向调整结果
if (order === 'desc') compareResult *= -1;
if (compareResult !== 0) return compareResult;
}
return 0;
};
}
/**
* 分页分割数据
* 传参:
* listRef:需要分页的总数居
* pageTotal:需要根据多少条数分页,默认为20条
* tablePageRef:传递的表格分页的对象,用于数据返回,为空时返回一个对象,不为空时直接赋值
* currentPage:当前页,默认获取为第一页
* isQuery:是否是根据当前页去查询数据,需要传递 currentPage
* isLoad:是否是滚动加载,滚动加载|分页加载,默认为true滚动加载
* 使用方式:
* const tablePage = reactive({
* pageSize: 0, //总页数
* currentPage: 1, //当前页
* total: 0,//总数
* pageTotal: 0,//每页页数
* resultData: [], //分割前的集合
* resultTableData: [], //分割后的集合
* currentTableData: [], //当前集合
* })
* const scrollTop = ref(0);
* const isScrollBottom = computed(()=>{})
* const handleScroll = ({ scrollTop:scroll })=>{}
* <el-table ref="tableRef" @scroll="handleScroll" >
*/
export const usePageFc = ({isQuery=false,listRef=[],pageTotal=20,tablePageRef,currentPage = 1,isLoad = true})=>{
const list = unref(listRef);
const tablePage = isRef(tablePageRef)?tablePageRef.value:tablePageRef;
if(tablePage){
if(!isQuery){
const result = [];
for (let i = 0; i < list?.length; i += pageTotal) {
result.push(list.slice(i, i + pageTotal));
}
tablePage.resultTableData = reactive(lodash.cloneDeep(result));
tablePage.resultData = list || [];
tablePage.total = list.length || 0;
tablePage.pageSize = result.length || 0;
tablePage.pageTotal = pageTotal;
}
if(currentPage <= tablePage.pageSize){
tablePage.currentTableData = tablePage.resultTableData[currentPage-1]
tablePage.currentPage = currentPage;
}else{ //末页处理
if(isLoad){ //滚动加载
tablePage.currentTableData = []
tablePage.currentPage = tablePage.pageSize;
}else{ //分页加载
tablePage.currentTableData = tablePage.resultTableData[tablePage.pageSize-1]
tablePage.currentPage = tablePage.pageSize;
}
}
return null;
}else{
return tablePage
}
}
index.vue
<template>
<div class="table">
<el-table ref="tableRef" v-loading="loading" :data="tableData" @scroll="handleScroll" :row-key="row => `${row.id}`">
</el-table>
</div>
<div class="pagination">
<!--
pager-count:总页数
total:总条目数
page-size:每页显示条目数
pager-count:最大页码数按钮,超过的显示...
hide-on-single-page: 只有一页时是否隐藏分页
-->
<!-- <el-pagination
v-model:current-page="search.pageNum"
v-model:page-size="search.pageSize"
:pager-count="pageCount || 0"
@update:page-size="handleSizeChange"
@update:current-page="handleCurrentChange"
:hide-on-single-page="false"
:page-sizes="[10, 20, 30, 50, 100,tableData?.length]"
size="small"
:disabled="false"
:background="false"
layout="total, slot, prev, pager, next, jumper"
:total="page.total"
>
<template #default>
<el-select style="margin-left: 1.2rem;" size="small"
v-model="search.pageSize"
@change="handleSizeChange">
<el-option label="10条/页" :value="10"/>
<el-option label="20条/页" :value="20"/>
<el-option label="30条/页" :value="30"/>
<el-option label="50条/页" :value="50"/>
<el-option label="100条/页" :value="100"/>
<el-option label="全部" :value="page.total"/>
</el-select>
</template>
</el-pagination> -->
</div>
</template>
<script setup>
import { computed, reactive, ref, onMounted } from "vue";
import { usePageFc } from "@/utils/common";
const tableRef = ref(null);
const loading = ref(false);
const tablePage = reactive({
pageSize: 0, //总页数
currentPage: 1, //当前页
total: 0,//总数
pageTotal: 0,//每页页数
resultData: [], //分割前的集合
resultTableData: [], //分割后的集合
currentTableData: [], //当前集合
})
const tableData = ref([]);
/**
* 获取所有集合
* relist:用于每次调用getList()获取最新的数据,否则通过点击事件触发getList()可能会存在数据残留导致数据异常
*/
const getList = (relist = true)=>{
if(relist){
tableData.value = [];
}
loading.value = true;
//发送一个axios请求获得集合(省略),可以使用 async/await
const array = [];
usePageFc({listRef: array,pageTotal: 50,tablePageRef: tablePage})
tableData.value.push(...tablePage.currentTableData);
loading.value = false
}
/**
* 鼠标下滑滚动条底部触发事件
*/
const scrollTop = ref(0);
const isScrollBottom = computed(()=>{
const element = tableRef.value?.$el.querySelector('.el- scrollbar__wrap') || {}; //.el-table__body-wrapper
const scrollHeight = element.scrollHeight; // 内容总高度
const clientHeight = element.clientHeight; // 可视高度
return scrollHeight - scrollTop.value <= clientHeight + 1; //触底条件(+1 避免浮点数误差)
})
/**
* 在表格中滑动滚动条触发的方法
*/
const handleScroll = ({ scrollTop:scroll })=>{
scrollTop.value = scroll;
if (isScrollBottom.value) {
usePageFc({isQuery: true,tablePageRef: tablePage,currentPage: tablePage.currentPage+1})
tableData.value.push(...tablePage.currentTableData);
}
}
/**
* 第一次加载页面的时候调用查询方法
*/
getList();
onMounted(()=>{
})
//- - - - - - - - - - - - - -
//分页处理相关,赋值变量不对,这个是后端分页相关,参考使用
const search = ref({
pageNum: 1, //当前页
pageSize: 20, //查询条数
sortList: [], //sortList 表格排序集合
filter: null
})
const page = ref({
total: 0,//总条数
pages: 0,//总页数
})
/**
* 计算分页的...隐藏显示,返回值必须是奇数,且范围在5到21之间
*/
const pageCount = computed(()=>{
if(page.value.pages<=10){
return 9;
}
return Math.round(page.value.pages/2) || 0;
})
/**
* 切换分页条件时的分页条数
*/
const handleSizeChange = (val) => {
if(val){
search.value.pageSize = val
getList();
}
}
/**
* 下一页时的当前页数
*/
const handleCurrentChange = (val) => {
if(val){
search.value.pageNum = val
getList();
}
}
</script>
<style scoped lang="scss">
/* 分页标签样式 */
.pagination {
margin: 1vh;
display: flex;
justify-content: flex-end;
}
</style>

被折叠的 条评论
为什么被折叠?



