TinyVue Pager 分页组件使用指南
组件介绍
Pager(分页)是数据列表中最常用的导航组件,用于将大量数据分页展示,帮助用户快速定位到目标数据。TinyVue 的 Pager 组件功能丰富,支持多种显示模式、自定义布局、前置拦截、自定义总条数等企业级特性,可满足从简单列表到复杂表格的各种分页场景。
引入方式:
js
import { TinyPager } from '@opentiny/vue'
基本用法
通过 total 设置数据总条数即可快速创建分页组件:
vue
<template>
<tiny-pager :total="50"></tiny-pager>
</template>
<script setup>
import { TinyPager } from '@opentiny/vue'
</script>
组件默认显示总条数、上一页、页码、下一页和页跳转。
设置当前页
通过 current-page 设置初始加载时的页码:
vue
<template>
<tiny-pager :current-page="2" :total="50"></tiny-pager>
</template>
<script setup>
import { TinyPager } from '@opentiny/vue'
</script>
每页显示数量
通过 page-size 设置每页显示条目数,通过 page-sizes 设置可选择的每页条数列表:
vue
<template>
<tiny-pager
mode="number"
:page-size="20"
:page-sizes="[10, 20, 50, 100]"
:total="100"
></tiny-pager>
</template>
<script setup>
import { TinyPager } from '@opentiny/vue'
</script>
page-sizes 默认为 [10, 20, 30, 40, 50, 100],可根据业务需求自定义。
五种显示模式
通过 mode 属性设置分页组件的渲染模式,不同模式是组件内置的 layout 配置,mode 优先级高于 layout:
| 模式 | 说明 |
|---|---|
number |
数字模式,显示页码按钮 |
simple |
简洁模式,仅显示"第 x/y 页" |
complete |
完整模式,显示所有子组件 |
fixed |
固定模式,页码按钮数量固定 |
simplest |
最简模式,仅显示前后翻页按钮 |
vue
<template>
<div>
<tiny-radio-group v-model="mode">
<tiny-radio-button label="number"></tiny-radio-button>
<tiny-radio-button label="simple"></tiny-radio-button>
<tiny-radio-button label="complete"></tiny-radio-button>
<tiny-radio-button label="fixed"></tiny-radio-button>
<tiny-radio-button label="simplest"></tiny-radio-button>
</tiny-radio-group>
<tiny-pager :mode="mode" :total="100"></tiny-pager>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { TinyPager, TinyRadioButton, TinyRadioGroup } from '@opentiny/vue'
const mode = ref('number')
</script>
自定义布局
通过 layout 属性自由组合分页子组件的显示内容和顺序,子组件间用英文逗号分隔:
| 子组件名 | 说明 |
|---|---|
total |
总条数 |
sizes |
每页条数选择器 |
prev |
上一页按钮 |
pager |
页码按钮 |
next |
下一页按钮 |
jumper |
页跳转输入框 |
current |
当前页码 |
slot |
默认插槽 |
vue
<template>
<div>
<!-- 带默认插槽的布局 -->
<tiny-pager layout="total, sizes, prev, pager, next, slot, jumper" :total="1000">
<template #default>
<span>共 100 页</span>
</template>
</tiny-pager>
<!-- 精简布局:条数选择 + 前后翻页 + 当前页 + 总条数 -->
<tiny-pager layout="sizes, prev, current, next, total" :total="1000"></tiny-pager>
</div>
</template>
<script setup>
import { TinyPager } from '@opentiny/vue'
</script>
默认 layout 为 'total, prev, pager, next, jumper'。
对齐方式
通过 align 设置分页组件的对齐方式,支持 left、center、right 三种:
vue
<template>
<div>
<tiny-radio-group v-model="align" type="button" :options="options"></tiny-radio-group>
<tiny-pager :align="align" :total="100"></tiny-pager>
</div>
</template>
<script setup>
import { reactive } from 'vue'
import { TinyPager, TinyRadioGroup } from '@opentiny/vue'
const align = reactive({
align: 'left',
options: ['left', 'center', 'right'].map((item) => ({ label: item, text: item }))
})
</script>
注意: Aurora、XDesign 主题下
align默认值为right。
禁用和尺寸
通过 disabled 禁用分页,通过 size 设置分页尺寸(支持 mini):
vue
<template>
<div>
是否禁用:<tiny-switch v-model="isDisabled"></tiny-switch>
<tiny-pager mode="number" :total="100" :disabled="isDisabled" />
<tiny-pager mode="number" :total="100" size="mini" :disabled="isDisabled" />
</div>
</template>
<script setup>
import { ref } from 'vue'
import { TinyPager, TinySwitch } from '@opentiny/vue'
const isDisabled = ref(false)
</script>
页码按钮数量
通过 pager-count 设置页码按钮显示的最多个数,当总页数超过该值时会折叠。合法值为 大于等于 5 且小于等于 21 的奇数:
vue
<template>
<tiny-pager layout="prev, pager, next" :total="200" :pager-count="15"></tiny-pager>
</template>
<script setup>
import { TinyPager } from '@opentiny/vue'
</script>
默认 pager-count 为 7。
总页数模式
除了通过 total(总条目数)设置分页,还可以通过 page-count 直接设置总页数:
vue
<template>
<tiny-pager :page-count="20"></tiny-pager>
</template>
<script setup>
import { TinyPager } from '@opentiny/vue'
</script>
提示:
total和page-count设置任意一个即可。如需支持page-sizes切换,则必须使用total。
自定义上下页按钮文本
通过 prev-text 和 next-text 替代默认图标,显示自定义文字:
vue
<template>
<tiny-pager
layout="prev, pager, next"
prev-text="上一页"
next-text="下一页"
:total="100"
></tiny-pager>
</template>
<script setup>
import { TinyPager } from '@opentiny/vue'
</script>
自定义总条数
通过 custom-total 自定义总条数的显示文本:
- 传值为
true时,自动按区间显示:099999 显示具体数值,10万99万显示"10万+",100万~999万显示"100万+",超过1000万显示"1千万+" - 传值为字符串时,直接显示该字符串
vue
<template>
<div>
<!-- 自动区间显示 -->
<tiny-pager
:current-page="currentPage"
@update:current-page="currentPage = $event"
:page-size="100"
layout="total, sizes, prev, pager, next"
:total="5000000"
:custom-total="true"
></tiny-pager>
<!-- 自定义文本 -->
<tiny-pager
:current-page="currentPage"
@update:current-page="currentPage = $event"
:page-size="100"
layout="total, sizes, prev, pager, next"
:total="5000000"
custom-total="条数超出百万"
></tiny-pager>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { TinyPager } from '@opentiny/vue'
const currentPage = ref(5)
</script>
总条数加载中
通过 show-total-loading 在总条数异步加载时显示加载状态:
vue
<template>
<div>
加载中:<tiny-switch v-model="totalLoading"></tiny-switch>
<tiny-pager
:page-size="10"
layout="total, sizes, prev, pager, next"
:total="100"
:show-total-loading="totalLoading"
></tiny-pager>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { TinyPager, TinySwitch } from '@opentiny/vue'
const totalLoading = ref(true)
</script>
单页时隐藏
通过 hide-on-single-page 设置当数据只有一页时是否隐藏分页组件:
vue
<template>
<div>
是否隐藏:<tiny-switch v-model="isHide"></tiny-switch>
<tiny-pager :hide-on-single-page="isHide" :total="1"></tiny-pager>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { TinyPager, TinySwitch } from '@opentiny/vue'
const isHide = ref(false)
</script>
分页变更前置处理
通过 is-before-page-change 开启前置处理特性。开启后,翻页或改变页大小不会立即生效,而是触发 before-page-change 事件,由用户决定是否继续:
vue
<template>
<tiny-pager
is-before-page-change
mode="number"
:total="200"
:current-page="currentPage"
@update:current-page="currentPage = $event"
@before-page-change="onBeforePageChange"
></tiny-pager>
</template>
<script setup>
import { ref } from 'vue'
import { TinyPager, TinyModal } from '@opentiny/vue'
const currentPage = ref(5)
function onBeforePageChange(param) {
const { callback, rollback } = param
TinyModal.confirm('您确定要继续变更操作吗?').then((res) => {
if (res === 'confirm') {
callback && callback() // 调用 callback 继续变更
} else {
rollback && rollback() // 调用 rollback 中止变更
}
})
}
</script>
事件回调参数 IBeforeChangeParam 包含:
| 字段 | 类型 | 说明 |
|---|---|---|
callback |
() => void |
调用则继续本次变更 |
rollback |
() => void |
调用则阻止本次变更 |
newPage |
number |
变更后所在页 |
newPageSize |
number |
变更后分页大小 |
currentPage |
number |
当前所在页 |
currentPageSize |
number |
当前分页大小 |
事件
| 事件名 | 回调参数 | 说明 |
|---|---|---|
current-change |
(currentPage: number) |
当前页改变时触发 |
size-change |
(pageSize: number) |
每页条目数改变时触发 |
prev-click |
(currentPage: number) |
点击上一页按钮后触发 |
next-click |
(currentPage: number) |
点击下一页按钮后触发 |
before-page-change |
IBeforeChangeParam |
前置处理模式下翻页前触发 |
事件使用示例
vue
<template>
<div>
<!-- 当前页改变 -->
<tiny-pager :total="100" mode="number" @current-change="handleCurrentChange"></tiny-pager>
<!-- 每页条目数改变 -->
<tiny-pager :total="100" mode="number" @size-change="handleSizeChange"></tiny-pager>
<!-- 上一页/下一页 -->
<tiny-pager :total="100" mode="number" @prev-click="prevClick" @next-click="nextClick"></tiny-pager>
</div>
</template>
<script setup>
import { TinyPager, TinyModal } from '@opentiny/vue'
function handleCurrentChange(val) {
console.log('当前页:', val)
}
function handleSizeChange(val) {
console.log('每页条目数:', val)
}
function prevClick(val) {
console.log('上一页后当前页:', val)
}
function nextClick(val) {
console.log('下一页后当前页:', val)
}
</script>
重要提示: 当在最后一页切换每页条目数时,会同时触发
current-change和size-change两个事件。如果两个事件调用同一函数(如后台拉取数据),需要做防抖处理。
change-compat 模式
默认情况下,手动改变 current-page 或 page-size 的值时不会触发对应的 change 事件。设置 change-compat 为 true 可以触发:
vue
<template>
<div>
<tiny-button @click="currentPage = 1">跳转第一页</tiny-button>
<tiny-pager
:total="100"
:current-page="currentPage"
mode="number"
change-compat
@current-change="onCurrentChange"
></tiny-pager>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { TinyPager, TinyButton } from '@opentiny/vue'
const currentPage = ref(10)
function onCurrentChange(val) {
console.log('current-change 触发,当前页:', val)
}
</script>
表格分页实战
Pager 组件常与 Grid 表格配合使用,实现服务端分页:
vue
<template>
<div>
<tiny-grid :data="tableData">
<tiny-grid-column type="index" width="60"></tiny-grid-column>
<tiny-grid-column field="name" title="名称"></tiny-grid-column>
<tiny-grid-column field="area" title="区域"></tiny-grid-column>
<tiny-grid-column field="address" title="地址"></tiny-grid-column>
</tiny-grid>
<tiny-pager
:current-page="pager.currentPage"
:page-size="pager.pageSize"
:total="pager.total"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
layout="total, sizes, prev, pager, next, jumper"
></tiny-pager>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { TinyGrid, TinyGridColumn, TinyPager } from '@opentiny/vue'
const pager = ref({
currentPage: 1,
pageSize: 5,
total: 0
})
const tableData = ref([])
// 模拟远程数据请求
async function fetchData() {
const { currentPage, pageSize } = pager.value
// 实际项目中替换为真实 API 调用
const res = await api.getList({ page: currentPage, size: pageSize })
tableData.value = res.data
pager.value.total = res.total
}
function handleCurrentChange(val) {
pager.value.currentPage = val
fetchData()
}
function handleSizeChange(val) {
pager.value.pageSize = val
pager.value.currentPage = 1 // 切换条数时重置到第一页
fetchData()
}
onMounted(() => {
fetchData()
})
</script>
下拉框显示位置
通过 popper-append-to-body 控制分页下拉框(每页条数选择器)是否插入到 body 元素下,默认为 true:
vue
<template>
<tiny-pager
mode="number"
:total="100"
:popper-append-to-body="false"
></tiny-pager>
</template>
<script setup>
import { TinyPager } from '@opentiny/vue'
</script>
通过 popper-class 为下拉框添加自定义类名:
vue
<template>
<tiny-pager
mode="number"
:total="100"
popper-class="my-pager-popper"
></tiny-pager>
</template>
<script setup>
import { TinyPager } from '@opentiny/vue'
</script>
API 参考
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| align | `'left' | 'center' | 'right'` |
| change-compat | boolean |
false |
手动改变值时是否触发对应 change 事件 |
| current-page | number |
1 |
当前所在页 |
| custom-total | `boolean | string` | false |
| disabled | boolean |
false |
是否禁用分页 |
| hide-on-single-page | boolean |
false |
只有一页时是否隐藏 |
| is-before-page-change | boolean |
false |
是否开启前置处理特性 |
| layout | string |
'total, prev, pager, next, jumper' |
组件布局 |
| mode | `'number' | 'simple' | 'complete' |
| next-text | string |
- | 下一页按钮文字 |
| page-count | number |
- | 总页数 |
| page-size | number |
10 |
每页显示条目数 |
| page-sizes | number[] |
[10, 20, 30, 40, 50, 100] |
可选每页条数列表 |
| pager-count | number |
7 |
页码按钮最多显示个数(5~21 奇数) |
| popper-append-to-body | boolean |
true |
下拉框是否插入 body |
| popper-class | string |
- | 下拉框自定义类名 |
| prev-text | string |
- | 上一页按钮文字 |
| show-total-loading | boolean |
false |
是否显示总条数加载中 |
| size | 'mini' |
- | 分页尺寸 |
| total | number |
- | 总条目数 |
| total-fixed-left | boolean |
false |
总条目数是否固定在左侧 |
| page-size-text | string |
'条/页' |
页码大小后置显示文本 |
Events
| 事件名 | 回调参数 | 说明 |
|---|---|---|
| before-page-change | IBeforeChangeParam |
前置处理模式下翻页前触发 |
| current-change | (currentPage: number) |
当前页改变时触发 |
| next-click | (currentPage: number) |
点击下一页后触发 |
| prev-click | (currentPage: number) |
点击上一页后触发 |
| size-change | (pageSize: number) |
每页条目数改变时触发 |
Slots
| 插槽名 | 说明 |
|---|---|
| default | 自定义内容,需在 layout 中列出 slot |
最佳实践
-
服务端分页优先 :对于大数据量场景,始终使用服务端分页而非前端分页,通过
current-change和size-change事件触发数据请求。 -
切换条数时重置页码 :
size-change事件中应将current-page重置为 1,避免出现空页。 -
防抖处理双触发 :在最后一页切换每页条数时,
current-change和size-change会同时触发,若两者调用同一数据请求函数,需做防抖处理。 -
前置拦截保护数据 :对于表单未保存等场景,使用
is-before-page-change+before-page-change事件拦截翻页操作,避免用户误操作丢失数据。 -
合理选择模式 :简单列表用
simple或simplest模式减少视觉负担;数据管理页面用number或complete模式提供完整导航能力。 -
大数据量用 custom-total :当总条数超过 10 万时,使用
custom-total简化显示,避免数字过长影响布局。 -
单页数据隐藏分页 :使用
hide-on-single-page在数据不足一页时自动隐藏分页,保持界面简洁。 -
layout 按需精简 :不需要页跳转就去掉
jumper,不需要条数选择就去掉sizes,减少不必要的交互元素。
OpenTiny NEXT 是一套企业智能前端开发解决方案,以生成式 UI 和 WebMCP 两大核心技术为基础,对现有传统的 TinyVue 组件库、TinyEngine 低代码引擎等产品进行智能化升级,构建出面向 Agent 应用的前端 NEXT-SDKs、AI Extension、TinyRobot智能助手、GenUI等新产品,实现AI理解用户意图自主完成任务,加速企业应用的智能化改造。