效果:
环境:
Windows10
vite: 2.8.0
vue3: 3.2.25
组件Pagination:
html基本构成如下(省略样式),后面再添加功能
从左到右分7个区域:
【上一页】按钮
【1】按钮
【…】省略号
【5 6 7 8 9】中间连续数字
【…】省略号
【n】最后一页按钮
【下一页】按钮
<template>
<div>
<!-- 上一页 -->
<button>上一页</button>
<!-- 第一页 -->
<button>1</button>
<!-- 省略号 -->
<span>...</span>
<!-- 中间连续页码 -->
<button>5</button>
<button>6</button>
<button>7</button>
<button>8</button>
<button>9</button>
<!-- 省略号 -->
<span>...</span>
<!-- 最后一页 -->
<button >n</button>
<!-- 下一页 -->
<button>下一页</button>
</div>
</template>
props
使用
defineProps
定义,三个参数
totalItems
,总的数量,比如数据库查询到的总的商品数量pageItems
,每一页展示的数量continues
,页码中间的连续数字的个数。(如上面的5 6 7 8 9,共5个数字。一般是奇数个,为了对称性)
const props = defineProps({
// 总数量
totalItems: Number,
// 每页的数量
pageItems: Number,
// 中间连续页码
continues: {
type: Number,
default: 5
}
})
data
通过
computed
,props计算总共多少页。初始化当前页码是第一页。
// 总页数
const totalPages = computed(() => Math.ceil(props.totalItems / props.pageItems))
// 当前页码
let currentNo = ref((totalPages.value > 0) ? 1 : 0)
最关键的,确定是否显示省略号?
通过计算中间
连续部分的起始和终止
位置:
- 总页数不够,那么肯定不用显示省略号
- 总页数够
- 判断起始位置,是否太靠近【页码1】按钮
- 判断终止位置,是否太靠近【页码n】按钮
// 计算中间连续页码的开始、结束位置
let startEnd = computed(() => {
let start = 0, end = 0
// 总页数不够,那么就不存在中间连续页码的问题了
if(totalPages.value < props.continues) {
start = 1
end = totalPages.value
} else {
// 连续页码数量的一半
const dx = Math.floor(props.continues / 2)
start = currentNo.value - dx
end = currentNo.value + dx
// 判断边界(假如有20页)
if(start < 1) {
start = 1
// 1 2 3 4 5 ... 20
end = props.continues
}
if(end > totalPages.value) {
end = totalPages.value
// 1 ... 16 17 18 19 20
start = totalPages.value - props.continues + 1
}
}
return {start, end}
})
点击跳转
改当前页码就行
/**
* 跳转页面
*/
function go(e) {
const target = e.target || e.srcElement
if(target.nodeName.toLowerCase() === 'button') {
const goIndex = target.getAttribute('go')
// 上一页、下一页
if(['-1', '+1'].includes(goIndex)) {
currentNo.value = goIndex - 0 + currentNo.value
if(currentNo.value < 1) currentNo.value = 1
if(currentNo.value > totalPages.value) currentNo.value = totalPages.value
} else {
currentNo.value = goIndex - '0'
}
}
}