一个通用的分页组件实现思路
<template>
<div v-if="totalPage > 1" class="pagination__wrap flex">
<a
v-if="pageNo > 1"
href="#"
class="lx-pagination__button"
@click="lastPage"
>
<i class="iconfont icon-shangyiye"/>
上一页
</a
>
<a
href="#"
class="xu-pagination-pager"
:class="{ active: pageNo === 1 }"
@click="pageChange(1)"
>1</a
>
<a v-if="start > 2" href="#" class="pagination-pager dot">...</a>
<a
v-for="item in pagerList"
:key="item"
href="#"
class="xu-pagination-pager"
:class="{ active: pageNo === item }"
@click="pageChange(item)"
>{{ item }}</a
>
<a v-if="end < totalPage - 1" href="#" class="pagination-pager dot"
>...</a
>
<a
href="#"
class="pagination-pager"
:class="{ active: pageNo === totalPage }"
@click="pageChange(totalPage)"
>{{ totalPage }}</a
>
<a
v-if="pageNo < totalPage"
href="#"
class="lx-pagination__button"
@click="nextPage"
>下一页
<i class="iconfont icon-xiayiye"/>
</a
>
</div>
</template>
<script lang="ts" setup>
const props = defineProps({
//分页总数
total: {
type: [Number,String],
default: 0,
},
//当前页码
pageNo: {
type: Number,
default: 0,
},
//每页数据条目
pageSize: {
type: Number,
default: 0,
},
//显示的page小方块个数
pagerCount: {
type: Number,
default: 7,
},
});
const { pagerCount } = toRefs(props);
const emit = defineEmits(["update:page-no", "update:page-size", "change"]);
const current = computed<number>({
set(val) {
emit("update:page-no", val);
},
get() {
return props.pageNo;
},
});
const size = computed<number>({
set(val) {
emit("update:page-size", val);
},
get() {
return props.pageSize;
},
});
const totalCount = ref(0);
const pagers = computed(()=>pagerCount.value - 2)
const totalPage = computed(() => {
return Math.ceil(totalCount.value / size.value);
});
const start = ref(2);
const end = computed(() => {
const num = Math.min(start.value + pagers.value - 1, totalPage.value - 1);
return num;
});
const pagerList = computed(() => {
let list = new Array(end.value - start.value + 1).fill(0);
list = list.map((_, i) => start.value + i);
return list;
});
watch(
() => current.value,
(val) => {
if(totalPage.value <=pagerCount.value){
start.value = 2
}
else if (val === start.value) {
start.value = Math.max(start.value - 2, 2);
} else if (val === end.value) {
start.value = Math.min(start.value + 2, totalPage.value - 1);
} else if (val === totalPage.value) {
start.value = Math.max(totalPage.value - pagers.value, 1);
} else if (val === 1) {
start.value = 2;
}
}
);
const pageChange = (i: number) => {
if (i === current.value) return;
current.value = i;
emit("change");
};
const nextPage = () => {
const i = Math.min(current.value + 1, totalPage.value);
pageChange(i);
};
const lastPage = () => {
const i = Math.max(current.value - 1, 1);
pageChange(i);
};
watch(
() => props.total,
(val) => {
totalCount.value =Number(val);
},
{
immediate: true,
}
);
</script>
65 天前