Radix Vue(Reka UI)分页组件 Pagination 完整指南:从零搭建可访问的分页导航
Radix VueReka UI分页组件 Pagination 完整指南从零搭建可访问的分页导航【免费下载链接】radix-vueAn open-source UI component library for building high-quality, accessible design systems and web apps for Vue. Previously Radix Vue项目地址: https://gitcode.com/GitHub_Trending/ra/radix-vue导读本指南以 Radix Vue现已更名并发布为Reka UI官方文档中的 Pagination 分页组件文档为核心结合 packages/core/src/Pagination 下的源码实现系统讲解该组件库中分页组件的全部 8 个组成部件Root / List / Item / Ellipsis / First / Prev / Next / Last、完整 API 参数、插槽与事件、页码区间计算算法以及省略号、首末页快捷按钮、受控页码等实战用法。读完本文你将能够独立在 Vue 3 项目中搭建一套具备键盘可访问性、可完全定制样式、支持受控/非受控两种模式的分页导航。组件概述与特性Pagination 组件用于将数据以分页的形式展示并提供页面之间的导航。根据官方文档该组件具备两大核心特性快速访问首页或末页通过PaginationFirst与PaginationLast部件让用户一键跳转到第一页或最后一页边缘页码常驻显示可选通过showEdges配置项决定是否始终展示第一页、最后一页与省略号。此外组件对辅助技术Assistive Technologies友好PaginationList负责将分页结构暴露给屏幕阅读器每个页码按钮自动带有aria-label如Page 3与aria-current标记导航按钮带aria-labelFirst Page等可读文本。安装Pagination 属于 Reka UI 组件库的一部分安装组件库后即可使用。pnpm add reka-uinpm install reka-uiyarn add reka-ui如果使用 Nuxt可在 nuxt.config.ts 中注册模块实现组件自动导入export default defineNuxtConfig({ modules: [reka-ui/nuxt], })如果使用 Vite unplugin-vue-components可借助官方提供的 Resolver 自动导入import Components from unplugin-vue-components/vite import RekaResolver from reka-ui/resolver export default defineConfig({ plugins: [ vue(), Components({ dts: true, resolvers: [ RekaResolver(), ], }), ], })组件源码位于 packages/core/src/Pagination本文以下所有源码引用均基于该目录。组件解剖Anatomy八个部件的组合Pagination 采用“Root 提供上下文 子部件消费上下文”的组合式结构。完整骨架如下来自官方文档包名reka-uiscript setup import { PaginationEllipsis, PaginationFirst, PaginationLast, PaginationList, PaginationListItem, PaginationNext, PaginationPrev, PaginationRoot } from reka-ui /script template PaginationRoot PaginationList v-slot{ items } PaginationFirst / PaginationPrev / template v-for(page, index) in items PaginationListItem v-ifpage.type page :keyindex / PaginationEllipsis v-else :keypage.type :indexindex #8230; /PaginationEllipsis /template PaginationNext / PaginationLast / /PaginationList /PaginationRoot /template各部件职责一览部件默认渲染元素职责PaginationRootnav包含全部分页部件提供页面状态与上下文PaginationListdiv渲染页码列表并向辅助技术暴露分页结构PaginationListItembutton渲染切换当前页码的按钮PaginationEllipsisdiv当列表过长且siblingCount较小、showEdges为true时的占位元素PaginationFirstbutton将页码设置为 1 的触发器PaginationPrevbutton将页码切换为上一页的触发器PaginationNextbutton将页码切换为下一页的触发器PaginationLastbutton将页码切换为最后一页的触发器源码层面的上下文机制PaginationRoot在 PaginationRoot.vue 中通过createContext/providePaginationRootContext向子部件注入page、onPageChange、pageCount、siblingCount、disabled、showEdges其余七个部件均通过injectPaginationRootContext()消费该上下文实现状态同步。API 参考以下 API 均来自官方文档对应的 meta 文件docs/content/meta 下以Pagination*.md命名的自动生成文档与源码 props 定义。RootPaginationRoot包含所有分页部件负责管理当前页码状态、计算总页数并提供上下文。Props名称说明类型必填默认值as渲染为的元素或组件可被asChild覆盖AsTag \| Component否navasChild将默认渲染元素替换为传入的子元素合并其 props 与行为详见 Composition 指南boolean否-defaultPage初始渲染时激活的页码用于不需要受控状态时number否1disabled为true时阻止用户与部件交互boolean否-itemsPerPage每页展示的数据条数number是-page受控的当前页码可绑定为v-model:pagenumber否-showEdges为true时始终展示第一页、最后一页与省略号boolean否falsesiblingCount当前页两侧展示的页码数量number否2total数据列表总条数number否0事件名称说明类型update:page页码值变化时的回调[value: number]插槽名称说明类型page当前页码状态numberpageCount总页数number从源码实现看PaginationRoot.vuepage通过useVModel与defaultPage结合实现受控/非受控双模式pageCount的计算逻辑为Math.max(1, Math.ceil(total / (itemsPerPage || 1)))即总页数最少为 1且itemsPerPage为 0 时不会产生除零错误。ListPaginationList用于展示页码列表同时让分页结构对辅助技术可访问。Props名称说明类型默认值as渲染元素AsTag \| ComponentdivasChild替换默认渲染元素boolean-插槽名称说明类型items页码条目{ type: ellipsis; } \| { type: page; value: number; }在 PaginationList.vue 中items由transform(getRange(page, pageCount, siblingCount, showEdges))计算得出——getRange输出(string | number)[]数字为页码、字符串为省略号标记transform将其转换为带type字段的对象数组供插槽消费。ItemPaginationListItem渲染用于切换当前页码的按钮需要传入value属性。此外官方文档为 Item 标注了两个数据属性Data Attributes属性值[data-selected]true当前页或空[data-type]pageProps名称说明类型必填默认值as渲染元素AsTag \| Component否buttonasChild替换默认渲染元素boolean否-value该页码按钮对应的页码值number是-源码实现细节PaginationListItem.vue通过isSelected computed(() rootContext.page.value props.value)判断当前选中项并输出data-selectedtrue与aria-currentpage自动添加aria-label如Page 5便于屏幕阅读器识别当as为button时自动注入typebutton避免表单中误触提交点击时调用rootContext.onPageChange(value)更新页码disabled状态下不响应。EllipsisPaginationEllipsis当列表很长、siblingCount设置得较小时用作“更多上一页/下一页”的视觉占位元素。官方文档标注的数据属性属性值[data-type]ellipsisProps名称说明类型默认值as渲染元素AsTag \| ComponentdivasChild替换默认渲染元素boolean-源码中PaginationEllipsis.vue它默认渲染一个div自带data-typeellipsis插槽默认内容为#8230;省略号字符。使用时应在外层模板中通过page.type ellipsis分支渲染并将index作为 key 传入。First / Prev / Next / Last 触发器四个导航触发器均默认渲染为button并自动附带aria-label部件默认 aria-label行为源码依据PaginationFirstFirst Page点击后onPageChange(1)当page 1或禁用时自动disabledPaginationPrevPrevious Page点击后onPageChange(page - 1)当page 1或禁用时自动disabledPaginationNextNext Page点击后onPageChange(page 1)当page pageCount或禁用时自动disabledPaginationLastLast Page点击后onPageChange(pageCount)当page pageCount或禁用时自动disabled它们均接受as与asChild两个 props默认button源码分别位于 PaginationFirst.vue、PaginationPrev.vue、PaginationNext.vue、PaginationLast.vue。注意这些触发器在到达边界首页/末页时会自动禁用且会继承 Root 的disabled状态无需手动维护禁用逻辑。页码区间计算原理PaginationList插槽中的items由 utils.ts 中的getRange函数生成算法参考自 chakra-ui/zag 的 pagination machine。理解它有助于你准确预测不同配置下的页码展示当showEdges为false默认窗口内最多展示siblingCount * 2 1个页码。总页数小于窗口大小时直接展示全部页码当前页靠近开头时展示前siblingCount * 2 1页当前页靠近末尾时展示末尾的siblingCount * 2 1页否则以当前页为中心展示左右各siblingCount页。当showEdges为true首尾页码与省略号常驻。算法用2 * siblingCount 5作为最大展示条目数2 个兄弟区间 2 个省略号 首尾 2 页 当前页 1 页再依据当前页位置计算左/右省略号是否需要展示最终输出[first, ELLIPSIS, middle..., ELLIPSIS, last]或省略号较少的形式。从源码结构看transform将区间内的数字映射为{ type: page, value }、将ellipsis字符串映射为{ type: ellipsis }这就是模板中page.type判断的由来。实战示例示例一带省略号的分页当数据量大时使用PaginationEllipsis作为前后更多条目的视觉提示官方文档示例script setup langts import { PaginationEllipsis, PaginationList, PaginationListItem, PaginationRoot } from reka-ui /script template PaginationRoot PaginationList v-slot{ items } template v-for(page, index) in items PaginationListItem v-ifpage.type page :keyindex / PaginationEllipsis v-else :keypage.type :indexindex #8230; /PaginationEllipsis /template /PaginationList /PaginationRoot /template示例二首/末页快捷按钮通过PaginationFirst与PaginationLast允许用户一键跳转到首页或末页官方文档示例script setup langts import { PaginationFirst, PaginationLast, PaginationList, PaginationListItem, PaginationRoot } from reka-ui /script template PaginationRoot PaginationList PaginationFirst / ... PaginationLast / /PaginationList /PaginationRoot /template示例三以编程方式控制当前页通过v-model:page将当前页码与外部响应式状态绑定实现程序化控制官方文档示例script setup langts import { PaginationRoot } from reka-ui import { ref } from vue import { Select } from ./custom-select const currentPage ref(1) /script template Select v-modelcurrentPage / PaginationRoot v-model:pagecurrentPage ... /PaginationRoot /template受控模式完全遵循 Reka UI 的 Controlled State 指南见 docs/content/docs/guides/controlled-state.md传page并监听update:page等价于v-model:page父组件持有状态若无需外部同步则使用defaultPage走非受控模式。示例四官方演示的完整配置组合仓库内的官方演示docs/components/demo/Pagination/tailwind/index.vue给出了贴近真实业务的完整配置展示了total、itemsPerPage、siblingCount、showEdges、defaultPage的组合用法以及基于data-selected属性的样式定制Tailwind 版script setup langts import { Icon } from iconify/vue import { PaginationEllipsis, PaginationFirst, PaginationLast, PaginationList, PaginationListItem, PaginationNext, PaginationPrev, PaginationRoot } from reka-ui /script template PaginationRoot :total100 :sibling-count1 :items-per-page10 show-edges :default-page2 PaginationList v-slot{ items } classflex items-center gap-1 text-stone-700 dark:text-white PaginationFirst classw-9 h-9 flex items-center justify-center ... Icon iconradix-icons:double-arrow-left / /PaginationFirst PaginationPrev class... Icon iconradix-icons:chevron-left / /PaginationPrev template v-for(page, index) in items PaginationListItem v-ifpage.type page :keyindex class...>.Button[data-selected] { background-color: rgb(255 255 255); color: var(--black-a11); } .Button:disabled { opacity: .5; }该示例中total100、itemsPerPage10意味着共 10 页showEdges开启后首尾页码与省略号常驻展示siblingCount1使当前页两侧各显示 1 个页码。键盘交互官方文档列出了该组件的键盘交互约定按键说明Tab将焦点移动到下一个可聚焦元素Space当焦点位于任一触发器页码按钮或导航按钮上时触发选中页码或箭头导航Enter当焦点位于任一触发器页码按钮或导航按钮上时触发选中页码或箭头导航结合源码可以确认所有触发器默认渲染为原生button因此浏览器原生提供Space/Enter激活能力组件在此基础上通过click完成页码跳转同时自动维护边界禁用与aria-current/aria-label等无障碍语义。常见配置速查需求配置方式仅展示少量相邻页码调小siblingCount如1始终显示第一页与最后一页设置show-edges为true并配合PaginationEllipsis一键跳转首页/末页加入PaginationFirst/PaginationLast外部同步当前页如 URL query、Pinia使用v-model:page受控模式简单场景不关心外部状态使用defaultPage非受控模式整体禁用分页交互在 Root 上设置disabled自定义渲染为其他元素使用as/asChild如将页码按钮渲染为a链接结语Reka UI 的 Pagination 组件通过 Root List Item Ellipsis 四个导航触发器的组合设计把分页的状态管理、页码计算与无障碍语义完整封装同时保留as/asChild、数据属性与插槽等高度的定制空间。结合官方文档示例与 packages/core/src/Pagination 源码你既可以开箱即用也能深入理解其页码区间算法进而根据业务需求大列表、数据表格、内容流等快速落地一套健壮、可访问且风格统一的分页导航。【免费下载链接】radix-vueAn open-source UI component library for building high-quality, accessible design systems and web apps for Vue. Previously Radix Vue项目地址: https://gitcode.com/GitHub_Trending/ra/radix-vue创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →