#Pagination 分页
带页码的分页组件,支持自定义页码数量、响应式折叠、不同尺寸和全局主题配置。
基于 Radix Vue Pagination 和 BrConfigProvider 实现。
#组件特性
- 📄 完整导航:显示页码、上一页/下一页、首页/末页控件。
- 👥 自定义邻页数:配置每侧可见的邻页数。
- 📱 边缘页码:支持显示首页和末页按钮。
- 📐 响应式折叠:在小屏幕自动折叠页码。
- 📏 多种尺寸:支持
sm、md、lg尺寸规格。 - 🎨 主题定制:基于
BrConfigProvider支持全局主题配置和 TailwindCSS 局部覆盖。
#基础用法
最基础的分页,通过 v-model:page 绑定当前页码。
<script setup lang="ts">
import { ref } from 'vue'
import {
BrPagination,
BrPaginationContent,
BrPaginationEllipsis,
BrPaginationFirst,
BrPaginationItem,
BrPaginationLast,
BrPaginationLink,
BrPaginationNext,
BrPaginationPrevious,
} from '@breezeui/vue'
const currentPage = ref(1)
</script>
<template>
<div class="flex flex-col items-center gap-4">
<BrPagination v-model:page="currentPage" :total="100" :sibling-count="1" show-edges>
<BrPaginationContent v-slot="{ items }">
<BrPaginationFirst />
<BrPaginationPrevious />
<template v-for="(page, index) in items" :key="index">
<BrPaginationItem v-if="page.type === 'page'">
<BrPaginationLink :value="page.value" :is-active="page.value === currentPage">
{{ page.value }}
</BrPaginationLink>
</BrPaginationItem>
<BrPaginationEllipsis v-else :key="page.type" :index="index" />
</template>
<BrPaginationNext />
<BrPaginationLast />
</BrPaginationContent>
</BrPagination>
<div class="text-sm text-muted-foreground">Current page: {{ currentPage }}</div>
</div>
</template>#自定义页码数量
通过 sibling-count 属性可以控制当前页码左右两侧显示的页码数量。
<script setup lang="ts">
import { ref } from 'vue'
import {
BrPagination,
BrPaginationContent,
BrPaginationEllipsis,
BrPaginationFirst,
BrPaginationItem,
BrPaginationLast,
BrPaginationLink,
BrPaginationNext,
BrPaginationPrevious,
} from '@breezeui/vue'
const currentPage = ref(1)
</script>
<template>
<div class="flex flex-col items-center gap-4">
<BrPagination v-model:page="currentPage" :total="100" :sibling-count="3" show-edges>
<BrPaginationContent v-slot="{ items }">
<BrPaginationFirst />
<BrPaginationPrevious />
<template v-for="(page, index) in items" :key="index">
<BrPaginationItem v-if="page.type === 'page'">
<BrPaginationLink :value="page.value" :is-active="page.value === currentPage">
{{ page.value }}
</BrPaginationLink>
</BrPaginationItem>
<BrPaginationEllipsis v-else :key="page.type" :index="index" />
</template>
<BrPaginationNext />
<BrPaginationLast />
</BrPaginationContent>
</BrPagination>
<div class="text-sm text-muted-foreground">Sibling count: 3</div>
</div>
</template>#不同尺寸
支持 xs, sm, md, lg, xl, 2xl 尺寸变体。
<script setup lang="ts">
import { ref } from 'vue'
import {
BrPagination,
BrPaginationContent,
BrPaginationEllipsis,
BrPaginationItem,
BrPaginationLink,
BrPaginationNext,
BrPaginationPrevious,
} from '@breezeui/vue'
import type { PaginationSize } from '@breezeui/vue'
const currentPage = ref(1)
const sizes: { label: string; value: PaginationSize }[] = [
{ label: 'Extra Small (xs)', value: 'xs' },
{ label: 'Small (sm)', value: 'sm' },
{ label: 'Medium (md)', value: 'md' },
{ label: 'Large (lg)', value: 'lg' },
{ label: 'Extra Large (xl)', value: 'xl' },
{ label: '2 Extra Large (2xl)', value: '2xl' },
]
</script>
<template>
<div class="flex flex-col items-center gap-8">
<div v-for="size in sizes" :key="size.value" class="flex flex-col items-center gap-2">
<span class="text-sm font-medium text-muted-foreground">{{ size.label }}</span>
<BrPagination v-model:page="currentPage" :total="50" :size="size.value">
<BrPaginationContent v-slot="{ items }">
<BrPaginationPrevious />
<template v-for="(page, index) in items" :key="index">
<BrPaginationItem v-if="page.type === 'page'">
<BrPaginationLink :value="page.value" :is-active="page.value === currentPage">
{{ page.value }}
</BrPaginationLink>
</BrPaginationItem>
<BrPaginationEllipsis v-else :key="page.type" :index="index" />
</template>
<BrPaginationNext />
</BrPaginationContent>
</BrPagination>
</div>
</div>
</template>#响应式折叠分页
结合 @vueuse/core 的 useWindowSize 动态控制 sibling-count 实现小屏自动折叠页码。
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useWindowSize } from '@vueuse/core'
import {
BrPagination,
BrPaginationContent,
BrPaginationEllipsis,
BrPaginationFirst,
BrPaginationItem,
BrPaginationLast,
BrPaginationLink,
BrPaginationNext,
BrPaginationPrevious,
} from '@breezeui/vue'
const currentPage = ref(1)
const { width } = useWindowSize()
const responsiveSiblingCount = computed(() => (width.value < 640 ? 0 : 2))
</script>
<template>
<div class="flex flex-col items-center gap-4">
<BrPagination v-model:page="currentPage" :total="100" :sibling-count="responsiveSiblingCount" show-edges>
<BrPaginationContent v-slot="{ items }">
<BrPaginationFirst />
<BrPaginationPrevious />
<template v-for="(page, index) in items" :key="index">
<BrPaginationItem v-if="page.type === 'page'">
<BrPaginationLink :value="page.value" :is-active="page.value === currentPage">
{{ page.value }}
</BrPaginationLink>
</BrPaginationItem>
<BrPaginationEllipsis v-else :key="page.type" :index="index" />
</template>
<BrPaginationNext />
<BrPaginationLast />
</BrPaginationContent>
</BrPagination>
<div class="text-sm text-muted-foreground">
Try resizing the window width (< 640px)
</div>
</div>
</template>#主题定制
BrPagination 组件的颜色(主色调、激活色)、圆角和尺寸完全基于 BrConfigProvider 提供的 CSS 变量实现。
<script setup lang="ts">
import { ref } from 'vue'
import {
BrConfigProvider,
BrPagination,
BrPaginationContent,
BrPaginationEllipsis,
BrPaginationFirst,
BrPaginationItem,
BrPaginationLast,
BrPaginationLink,
BrPaginationNext,
BrPaginationPrevious,
} from '@breezeui/vue'
const currentPage = ref(1)
const customTheme = {
primary: '#10b981', // Custom active color (Emerald-500)
radius: 1.5, // Larger border radius
}
</script>
<template>
<BrConfigProvider :theme="customTheme">
<div class="flex justify-center p-4 border rounded-lg bg-background">
<BrPagination v-model:page="currentPage" :total="100" :sibling-count="1" show-edges>
<BrPaginationContent v-slot="{ items }">
<BrPaginationFirst />
<BrPaginationPrevious />
<template v-for="(page, index) in items" :key="index">
<BrPaginationItem v-if="page.type === 'page'">
<BrPaginationLink :value="page.value" :is-active="page.value === currentPage">
{{ page.value }}
</BrPaginationLink>
</BrPaginationItem>
<BrPaginationEllipsis v-else :key="page.type" :index="index" />
</template>
<BrPaginationNext />
<BrPaginationLast />
</BrPaginationContent>
</BrPagination>
</div>
</BrConfigProvider>
</template>你也可以通过 TailwindCSS 局部覆盖:
<BrPaginationLink class="rounded-full border-blue-500 text-blue-500" />#API
#BrPagination
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
total | number | - | 数据总数 |
page (v-model) | number | 1 | 当前页码 |
itemsPerPage | number | 10 | 每页显示条数 |
siblingCount | number | 1 | 当前页左右两侧显示的页码数量 |
showEdges | boolean | false | 是否始终显示首尾页码 |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'md' | 分页按钮尺寸,会覆盖全局配置 |
#BrPaginationLink
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | number | - | 对应页码的值 |
isActive | boolean | false | 是否为激活状态 |
disabled | boolean | false | 是否禁用 |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | - | 尺寸大小 |
#其他子组件
BrPaginationPrevious、BrPaginationNext、BrPaginationFirst、BrPaginationLast 等均支持传递 class 以通过 TailwindCSS 进行样式覆盖。