179 lines
9.3 KiB
Markdown
179 lines
9.3 KiB
Markdown
---
|
||
name: pagination-component
|
||
overview: 按开发规范并参考 antdv-next 设计,新增 fms-vue 的 Pagination 分页组件(含页码折叠、sizeChanger、quickJumper、showTotal、非受控/受控双 v-model),并在 App.vue 演示页补充导航与示例。
|
||
design:
|
||
architecture:
|
||
framework: vue
|
||
styleKeywords:
|
||
- 简洁
|
||
- 中性色
|
||
- 主色强调
|
||
- 等宽页码
|
||
- 清晰状态
|
||
fontSystem:
|
||
fontFamily: PingFang SC
|
||
heading:
|
||
size: 14px
|
||
weight: 600
|
||
subheading:
|
||
size: 14px
|
||
weight: 400
|
||
body:
|
||
size: 14px
|
||
weight: 400
|
||
colorSystem:
|
||
primary:
|
||
- "#0f172b"
|
||
- "#ffffff"
|
||
background:
|
||
- "#ffffff"
|
||
- "#f5f6f8"
|
||
- "#f1f5f9"
|
||
text:
|
||
- "#1f2329"
|
||
- "#86909c"
|
||
- "#ffffff"
|
||
functional:
|
||
- "#e5e6eb"
|
||
- "#c9cdd4"
|
||
- "#f2f3f5"
|
||
todos:
|
||
- id: create-pagination-component
|
||
content: 使用 [skill:ui-ux-pro-max] 核对分页交互规范后,创建 pagination.vue:props/emits、页码窗口算法、受控/非受控双模式
|
||
status: completed
|
||
- id: build-pagination-template
|
||
content: 完成 pagination.vue 模板:页码/省略号/prev-next、sizeChanger 复用 Select、quickJumper 复用 Input、showTotal 与 ARIA
|
||
status: completed
|
||
dependencies:
|
||
- create-pagination-component
|
||
- id: write-pagination-styles
|
||
content: 编写 index.scss:页码项各状态、省略号 hover 双箭头、布局间距,全部复用 --fms-* token
|
||
status: completed
|
||
dependencies:
|
||
- build-pagination-template
|
||
- id: add-pagination-demo
|
||
content: App.vue 新增 Pagination 导航项与演示 section(基础/条数切换/快速跳转/总数/禁用/单页隐藏),静态检查后汇报
|
||
status: in_progress
|
||
dependencies:
|
||
- write-pagination-styles
|
||
---
|
||
|
||
## 产品概述
|
||
|
||
在 fms-vue 组件库中新增 Pagination 分页组件:参考 antdv-next 的 Pagination 设计(current/pageSize 双 v-model、页码窗口与省略号跳转、每页条数切换、快速跳转、总数显示),按本项目开发规范做轻量化实现,并在演示站 App.vue 中新增展示。
|
||
|
||
## 核心功能
|
||
|
||
- 页码导航:首页 / 尾页固定展示,当前页前后各 1 页,中间用省略号折叠;省略号点击跳 ±5 页;上一页 / 下一页箭头按钮
|
||
- 每页条数切换(showSizeChanger):复用 Select 组件,选项默认 [10, 20, 50, 100]
|
||
- 快速跳转(showQuickJumper):复用 Input 数字输入,Enter 跳转到指定页
|
||
- 总数显示(showTotal):默认显示「共 X 条」,支持插槽自定义文案
|
||
- 受控 / 非受控双模式:不传 v-model 时组件内部维护 current 与 pageSize(参照 Tabs 先例)
|
||
- 边界与禁用:单页时可选隐藏(hideOnSinglePage)、整组禁用、页码越界自动回退、页码 1 时上一页禁用等
|
||
- 可访问性:页码按钮原生 disabled、当前页 aria-current、图标按钮带 aria-label、focus-visible 焦点样式
|
||
|
||
## 视觉效果
|
||
|
||
- 页码项为 32px 等宽方形按钮,与控件高度 token 一致;当前页主色填充,hover/焦点主色描边,禁用降级为灰
|
||
- 整体水平排列、间距 8px,与 Tabs 等现有组件间距体系一致;深色模式自动适配 tokens
|
||
|
||
## 技术栈
|
||
|
||
- Vue 3 `<script setup>` + Vite + Sass,与现有组件库一致
|
||
- 图标按需导入 Lucide(ChevronLeft / ChevronRight / ChevronsLeft / ChevronsRight / Ellipsis)
|
||
- 复用现有 Select(每页条数)、Input type="number"(快速跳转)、Button(无需,页码项为原生 button)
|
||
- 样式全部复用 `--fms-*` token,不新增 token(页码项尺寸由 `--fms-control-height` 派生)
|
||
|
||
## 实现方案
|
||
|
||
### API 设计
|
||
|
||
Props(均带类型与默认值,枚举带 validator):
|
||
|
||
| Prop | 类型 | 默认 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| current | Number | undefined | 当前页(受控时传,非受控不传) |
|
||
| pageSize | Number | 10 | 每页条数 |
|
||
| total | Number | 0 | 总条数 |
|
||
| disabled | Boolean | false | 整组禁用 |
|
||
| hideOnSinglePage | Boolean | false | 仅 1 页时隐藏 |
|
||
| showSizeChanger | Boolean | false | 显示每页条数切换 |
|
||
| pageSizeOptions | Array | [10, 20, 50, 100] | 每页条数选项 |
|
||
| showQuickJumper | Boolean | false | 显示快速跳转 |
|
||
| showTotal | Boolean | false | 显示「共 X 条」(配合 #showTotal 插槽自定义) |
|
||
|
||
|
||
事件:`update:current`、`update:pageSize`、`change(page, pageSize)`、`showSizeChange(current, size)`(pageSize 变化时触发)。
|
||
|
||
插槽:`showTotal`(作用域 `{ total, from, to }`,用于自定义总数文案)。
|
||
|
||
### 页码窗口算法
|
||
|
||
`totalPages = Math.max(1, Math.ceil(total / pageSize))`;`pageItems` 计算属性生成:
|
||
|
||
- totalPages ≤ 7:展示全部页码
|
||
- 否则:固定含 1 与 totalPages,含 current-1/current/current+1;中间空隙插入 `jump-prev` / `jump-next` 省略号项(点击跳 `current ± 5`,clamp 到 [1, totalPages])
|
||
|
||
每个项结构:`{ type: 'page'|'jump-prev'|'jump-next'|'prev'|'next', page }`,模板按 type 渲染;全部用 computed 预生成,不在模板中调用创建对象的函数。
|
||
|
||
### 受控 / 非受控双模式(参照 Tabs 先例)
|
||
|
||
- `innerCurrent` / `innerPageSize` 两个内部 ref;`current` prop 未传时用内部值
|
||
- 变化时统一走 `applyChange(page, pageSize)`:受控模式 emit `update:current` / `update:pageSize`,非受控模式写内部 ref,均 emit `change`;pageSize 变化额外 emit `showSizeChange`
|
||
- 越界回退:current 超出 [1, totalPages] 时展示层 clamp 到边界(受控不写回,保持受控语义)
|
||
- pageSize 变化导致 current 超界时,非受控模式同步调整 current
|
||
|
||
### 子部件复用要点
|
||
|
||
- **sizeChanger**:`<Select :model-value="pageSize" :options="pageSizeOptions" :filterable="false" @update:model-value="onSizeChange" style="width: 76px; min-width: 76px" />`。Select 根默认 `min-width: 200px`,须用内联样式覆盖宽度,浮层仍跟随触发器
|
||
- **quickJumper**:`<Input type="number" ...>`,本地 ref 维护输入值,Enter 提交(clamp 到 [1, totalPages] 后触发跳转并清空)、失焦清空;Enter 监听依赖 Input 根元素事件透传,若透传受限则在外层 div 监听 keydown(冒泡兜底)
|
||
- 禁用时 Select/Input 同步传 disabled
|
||
|
||
### 键盘与 ARIA
|
||
|
||
- 容器 `role="navigation"` + `aria-label="分页"`
|
||
- 当前页码项 `aria-current="page"`;prev/next 图标按钮 `aria-label="上一页" / "下一页"`
|
||
- 所有页码项为原生 `<button type="button">`,禁用状态同时反映原生 disabled 与视觉(not-allowed)
|
||
- `:focus-visible` 主色 outline(复用 Tabs/Button 焦点规范)
|
||
|
||
### 性能与可靠性
|
||
|
||
- 页码数组、总页数、显示范围(from/to)均为 computed 缓存,无重复计算
|
||
- 无高频事件、无全局监听器、无 watch 深度监听;跳转输入仅本地 ref
|
||
- 图标按需导入,样式只定义一套状态选择器,无 !important、无多余包裹层
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
fms-vue/src/components/ui/pagination/
|
||
├── pagination.vue # [NEW] 分页主组件:页码窗口算法、受控/非受控切换、模板(页码/省略号/prev-next/sizeChanger/quickJumper/showTotal)
|
||
└── index.scss # [NEW] 样式:页码项各状态(默认/hover/focus/active/disabled)、省略号、布局与间距,全部复用 --fms-* token
|
||
fms-vue/src/App.vue # [MODIFY] categories 通用分组新增 { key: 'pagination', label: 'Pagination 分页' };新增演示 section
|
||
```
|
||
|
||
不新增其他文件;分页逻辑单文件承载,无 barrel index。
|
||
|
||
## 已知风险与规避
|
||
|
||
- Select 宽度覆盖:内联 style 覆盖根 min-width,已在上文写明
|
||
- Input 事件透传:keydown.enter 若未透传则外层包装监听,方案已定
|
||
- 省略号 hover 双箭头效果依赖 CSS(hover 切换图标),用两个图标 + CSS 显隐,成本低;`prefers-reduced-motion` 下关闭过渡
|
||
|
||
## 设计风格
|
||
|
||
延续项目现有 tokens 驱动的简洁中性风格,参考 antd Pagination 经典形态,保证与 Button / Tabs 等组件视觉一致。
|
||
|
||
- 布局:整体 inline-flex 水平排列、gap 8px;页码项与箭头按钮等高 32px(复用 --fms-control-height);showTotal 居左、sizeChanger 与 quickJumper 居右;空间不足时允许 flex-wrap 换行
|
||
- 页码项:32px 等宽方形(min-width 与 height 同值),圆角 6px;默认白底 1px 边框 + 次级文字;hover 主色描边与文字;当前页主色填充 + 白色文字 + 字重 600(不只靠颜色表达选中);禁用降为灰底灰字 not-allowed
|
||
- 省略号项:居中 Ellipsis 图标,hover 时切换为 ChevronsLeft / ChevronsRight 双箭头并显示主色,点击跳 ±5 页
|
||
- 交互反馈:hover 与 :focus-visible 均呈现主色描边;过渡仅限颜色/边框低成本属性,prefers-reduced-motion 关闭
|
||
- 数字稳定性:页码数字使用 tabular-nums,切换页时不抖动
|
||
- 暗色模式:所有颜色走 --fms-* token,.dark 自动适配,无需额外样式
|
||
|
||
## Agent Extensions
|
||
|
||
### Skill
|
||
|
||
- **ui-ux-pro-max**
|
||
- 用途:实现前查询分页组件(pagination)的键盘操作、可访问性与视觉细节 UX 规则,核对页码窗口交互是否符合常见实践
|
||
- 预期结果:获得分页导航的交互/可访问性指引(如页码按钮焦点、aria-current、省略号跳转习惯);若查询无有效输出,则回退到开发规范内置的交互底线(focus-visible、ARIA、禁用语义) |