Files
cz-web/src/components/PaginationBar.vue
2026-09-30 15:55:36 +08:00

109 lines
2.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { computed } from 'vue'
interface Props {
page: number
pageSize: number
total: number
}
const props = defineProps<Props>()
const emit = defineEmits<{ pageChange: [page: number] }>()
const pageCount = computed(() => Math.max(1, Math.ceil(props.total / props.pageSize)))
/** 页码序列:≤7 全部展示,否则首尾 + 当前页窗口(… 省略) */
const pages = computed<Array<number | '...'>>(() => {
const n = pageCount.value
const { page } = props
if (n <= 7) return Array.from({ length: n }, (_, i) => i + 1)
const window: Array<number | '...'> = []
for (let p = page - 1; p <= page + 1; p++) {
if (p >= 1 && p <= n) window.push(p)
}
if (page > 3) window.unshift('...')
if (page < n - 2) window.push('...')
return [1, ...window.filter((item) => item !== 1 && item !== n), n].filter(
(item, index, arr) => arr.indexOf(item) === index,
)
})
function go(page: number): void {
if (page < 1 || page > pageCount.value || page === props.page) return
emit('pageChange', page)
}
</script>
<template>
<nav class="pagination" aria-label="分页">
<button
class="pagination__btn"
:disabled="page <= 1"
@click="go(page - 1)"
>
‹
</button>
<button
v-for="(item, index) in pages"
:key="`${item}-${index}`"
class="pagination__btn"
:class="{ 'is-active': item === page, 'is-ellipsis': item === '...' }"
:disabled="item === '...'"
@click="go(item as number)"
>
{{ item }}
</button>
<button
class="pagination__btn"
:disabled="page >= pageCount"
@click="go(page + 1)"
>
›
</button>
</nav>
</template>
<style lang="less" scoped>
.pagination {
.flex(row, center);
gap: @spacing-xs; // 盒间距 6 × 0.77 ≈ 5
padding: 12px 0; // 网格 → 分页 36 × 0.77(叠加主栏 gap 18)
&__btn {
.flex(row, center);
min-width: 20px; // 设计15 页码盒 26 × 0.77
height: 25px; // 设计 32 × 0.77
padding: 0 3px;
border: 1px solid @border-color;
border-radius: @radius-sm;
background: @white;
color: @text-color-secondary; // 设计15 实取 rgba(107,114,128)
font-size: 11px; // 设计 12 → 9.2,取可读下限 11
transition: all 0.2s;
&:hover:not(:disabled):not(.is-ellipsis) {
border-color: @primary-strong;
color: @primary-strong;
}
&.is-active {
border-color: @cases-page-active-bg;
background: @cases-page-active-bg;
color: @primary-strong; // 设计15 当前页文字 rgba(2,79,255)
}
&.is-ellipsis {
border-color: transparent;
background: transparent;
cursor: default;
}
&:disabled:not(.is-ellipsis) {
opacity: 0.4;
cursor: not-allowed;
}
}
}
</style>