15 KiB
15 KiB
分页组件样式优化更新
📅 更新时间
2025-10-16
🎯 更新概述
对全系统的分页组件进行美观度和用户体验优化,解决之前版本中分页样式变形和不美观的问题。
✨ 主要改进
1. 视觉设计优化
统一的按钮样式
- ✅ 所有按钮使用相同的高度 (h-9) 和宽度 (w-9)
- ✅ 当前页使用绿色主题高亮 (
bg-green-600) - ✅ 其他页使用 outline 样式
- ✅ 禁用状态自动应用半透明效果
响应式布局
桌面端:
┌─────────────────────────────────────────────────────────────┐
│ 每页显示 [10▼] 条 ⏮ ◀ [1] 2 3 ... 10 ▶ ⏭ 显示 1-10 至,共 95 条 │
└─────────────────────────────────────────────────────────────┘
移动端:
┌──────────────────────┐
│ [10▼] 条 │
├──────────────────────┤
│ ◀ [1] 2 3 ... 10 ▶ │
├──────────────────────┤
│ 共 95 条 │
└──────────────────────┘
2. 功能增强
新增快捷按钮
| 按钮 | 图标 | 功能 | 显示条件 |
|---|---|---|---|
| ⏮ 第一页 | ChevronsLeft | 跳转到第1页 | 桌面端显示 |
| ◀ 上一页 | ChevronLeft | 上一页 | 始终显示 |
| ▶ 下一页 | ChevronRight | 下一页 | 始终显示 |
| ⏭ 最后页 | ChevronsRight | 跳转到最后页 | 桌面端显示 |
优化的页码显示
// 页码显示策略
totalPages ≤ 5: 显示所有页码
例: [1] [2] [3] [4] [5]
totalPages > 5: 智能省略
当前页靠前: [1] [2] [3] ... [10]
当前页居中: [1] ... [5] [6] [7] ... [10]
当前页靠后: [1] ... [8] [9] [10]
3. 用户体验提升
统计信息优化
// 桌面端完整信息
显示 1 至 10 条,共 95 条
// 移动端简化信息
共 95 条
交互反馈
- ✅ 当前页绿色高亮,一眼识别
- ✅ 禁用按钮自动变灰,不可点击
- ✅ 鼠标悬停效果流畅
- ✅ 数字加粗显示,更清晰
4. 布局改进
Card 内部分页
<Card>
<Table>
{/* 表格内容 */}
</Table>
{/* 分页组件 - 带顶部边框 */}
<DataPagination {...props} />
</Card>
特点:
- ✅ 顶部边框分隔表格和分页区域
- ✅ 背景色与 Card 一致
- ✅ 内边距统一 (px-4 py-4)
- ✅ 响应式间距 (gap-4)
📐 技术细节
组件结构
<div className="border-t bg-background">
<div className="flex flex-col gap-4 px-4 py-4 sm:flex-row sm:items-center sm:justify-between">
{/* 左:每页数量 */}
<div className="flex items-center gap-2">
<span>每页显示</span>
<Select />
<span>条</span>
</div>
{/* 中:分页器 */}
<div className="flex items-center gap-2">
<Button>⏮</Button> {/* 第一页 - 桌面端 */}
<Button>◀</Button> {/* 上一页 */}
<div className="flex items-center gap-1">
{/* 页码按钮 */}
</div>
<Button>▶</Button> {/* 下一页 */}
<Button>⏭</Button> {/* 最后页 - 桌面端 */}
</div>
{/* 右:统计信息 */}
<div className="text-sm text-muted-foreground">
<span>显示 1 至 10 条,</span>
<span>共 95 条</span>
</div>
</div>
</div>
样式类说明
容器样式
className="border-t bg-background"
// border-t: 顶部边框,分隔表格
// bg-background: 背景色与卡片一致
布局样式
className="flex flex-col gap-4 px-4 py-4 sm:flex-row sm:items-center sm:justify-between"
// flex-col: 移动端垂直排列
// sm:flex-row: 桌面端水平排列
// gap-4: 元素间距
// px-4 py-4: 内边距
// sm:justify-between: 桌面端两端对齐
按钮样式
// 当前页按钮
className="h-9 w-9 p-0 bg-green-600 hover:bg-green-700 text-white"
// 普通页按钮
className="h-9 w-9 p-0"
variant="outline"
// 导航按钮
className="h-9 w-9 p-0"
variant="outline"
disabled={!canPreviousPage}
颜色方案
| 元素 | 颜色 | Tailwind 类 |
|---|---|---|
| 当前页背景 | 绿色 | bg-green-600 |
| 当前页悬停 | 深绿 | hover:bg-green-700 |
| 当前页文字 | 白色 | text-white |
| 普通按钮 | 边框 | variant="outline" |
| 辅助文字 | 灰色 | text-muted-foreground |
| 数字强调 | 前景色 | text-foreground |
🎨 设计原则
1. 一致性
- ✅ 所有按钮相同尺寸 (9x9)
- ✅ 统一的间距 (gap-1, gap-2, gap-4)
- ✅ 绿色主题贯穿系统
2. 清晰性
- ✅ 当前页绿色高亮
- ✅ 数字加粗显示
- ✅ 禁用状态明显
3. 响应式
- ✅ 移动端简化显示
- ✅ 桌面端完整功能
- ✅ 流畅的布局切换
4. 可访问性
- ✅ 禁用状态自动处理
- ✅ 图标含义清晰
- ✅ 文字信息完整
📱 响应式设计
断点策略
// 移动端 (< 640px)
- 垂直堆叠布局
- 隐藏"每页显示"文字
- 隐藏第一页/最后页按钮
- 简化统计信息
// 桌面端 (≥ 640px)
- 水平排列布局
- 显示完整文字
- 显示所有快捷按钮
- 完整统计信息
自适应元素
每页数量选择器
// 移动端
[10▼] 条
// 桌面端
每页显示 [10▼] 条
导航按钮
// 移动端
◀ [1] [2] [3] ... [10] ▶
// 桌面端
⏮ ◀ [1] [2] [3] ... [10] ▶ ⏭
统计信息
// 移动端
共 95 条
// 桌面端
显示 1 至 10 条,共 95 条
🔧 使用示例
基础用法
import { usePagination } from '../lib/usePagination';
import { DataPagination } from './ui/data-pagination';
function MyList({ data }) {
// 初始化分页
const pagination = usePagination(data, 10);
return (
<Card>
<Table>
<TableBody>
{pagination.paginatedData.map(item => (
<TableRow key={item.id}>
{/* 渲染行 */}
</TableRow>
))}
</TableBody>
</Table>
{/* 分页组件 */}
<DataPagination
currentPage={pagination.currentPage}
totalPages={pagination.totalPages}
pageSize={pagination.pageSize}
totalItems={data.length}
startIndex={pagination.startIndex}
endIndex={pagination.endIndex}
onPageChange={pagination.goToPage}
onPageSizeChange={pagination.setPageSize}
canPreviousPage={pagination.canPreviousPage}
canNextPage={pagination.canNextPage}
/>
</Card>
);
}
自定义每页选项
<DataPagination
{...paginationProps}
pageSizeOptions={[5, 10, 20, 50]} // 自定义选项
/>
与筛选配合
// 先筛选,后分页
const filteredData = data.filter(/* 筛选条件 */);
const pagination = usePagination(filteredData, 10);
// 分页组件使用筛选后的数据量
<DataPagination
{...pagination}
totalItems={filteredData.length} // 使用筛选后的总数
/>
📁 修改文件
核心文件
- ✅
/components/ui/data-pagination.tsx- 完全重写 - ✅
/lib/usePagination.ts- 保持不变
已应用分页的组件
- ✅
/components/machinery/MachineryList.tsx- 农机列表 - ✅
/components/machinery/driver/DriverList.tsx- 驾驶员列表 - ✅
/components/machinery/driver/DriverTask.tsx- 任务列表 - ✅
/components/field/FieldList.tsx- 地块列表
待应用的组件
根据需要,可以在以下组件中添加分页:
- 维护记录列表
- 问题管理列表
- 培训记录列表
- 违规记录列表
- 其他需要分页的列表
🎯 优化前后对比
优化前的问题
❌ 布局问题:
- 英文 "Previous" 和 "Next" 不统一
- 按钮大小不一致
- 移动端显示拥挤
- 间距不规范
❌ 视觉问题:
- 当前页不够突出
- 缺少快捷跳转按钮
- 统计信息不够清晰
- 缺少分隔线
❌ 体验问题:
- 禁用状态不明显
- 缺少第一页/最后页快捷键
- 移动端信息过多
优化后的改进
✅ 布局优化:
- 统一的中文界面
- 所有按钮 9x9 方形
- 响应式布局完善
- 规范的间距系统
✅ 视觉优化:
- 绿色主题突出当前页
- 4个导航按钮覆盖所有场景
- 数字加粗,信息清晰
- 顶部边框分隔区域
✅ 体验优化:
- 禁用状态自动变灰
- 桌面端快捷跳转
- 移动端简化信息
- 流畅的交互反馈
💡 最佳实践
1. 何时使用分页
适合使用分页:
- ✅ 数据量 > 20 条
- ✅ 列表型数据展示
- ✅ 需要快速浏览
- ✅ 性能要求高
不适合使用分页:
- ❌ 数据量 < 10 条
- ❌ 需要全局搜索
- ❌ 数据关联性强
- ❌ 需要打印完整列表
2. 每页数量建议
| 场景 | 推荐数量 | 说明 |
|---|---|---|
| 简单列表 | 20-50 | 少字段,快速浏览 |
| 详细列表 | 10-20 | 多字段,仔细查看 |
| 移动端 | 10-15 | 屏幕空间有限 |
| 桌面端 | 20-50 | 屏幕空间充足 |
3. 性能优化
分页优化:
// ✅ 推荐:先筛选后分页
const filtered = data.filter(filterFn);
const pagination = usePagination(filtered, 10);
// ❌ 避免:分页后筛选
const pagination = usePagination(data, 10);
const filtered = pagination.paginatedData.filter(filterFn);
搜索优化:
// ✅ 推荐:搜索后重置页码
const handleSearch = (keyword) => {
setSearchKeyword(keyword);
pagination.goToPage(1); // 重置到第一页
};
4. 用户体验
默认设置:
- ✅ 默认第1页
- ✅ 默认每页10条(简单列表)或 20条(详细列表)
- ✅ 筛选后自动跳转第1页
交互反馈:
- ✅ 当前页明显标识
- ✅ 禁用按钮不可点击
- ✅ 显示完整统计信息
🐛 常见问题
Q1: 分页组件在哪里显示?
A: 应该在 Card 组件内部,Table 组件下方。
<Card>
<Table>
{/* 表格内容 */}
</Table>
<DataPagination {...props} /> {/* 这里 */}
</Card>
Q2: 为什么切换每页数量会回到第一页?
A: 这是设计行为。切换每页数量时,当前页码可能超出新的总页数,所以自动重置到第1页。
Q3: 移动端为什么看不到第一页/最后页按钮?
A: 为了节省空间,移动端隐藏了这些快捷按钮。用户可以通过点击页码或多次点击上一页/下一页来导航。
Q4: 如何修改绿色主题?
A: 修改 data-pagination.tsx 中的样式:
// 找到这行
className="bg-green-600 hover:bg-green-700 text-white"
// 改为你想要的颜色,例如蓝色
className="bg-blue-600 hover:bg-blue-700 text-white"
Q5: 分页数据量为0时会显示什么?
A: 当 totalItems === 0 时,分页组件会返回 null,不显示任何内容。
Q6: 如何处理分页和筛选同时使用?
A: 先筛选数据,然后用筛选后的数据初始化分页:
const filteredData = data.filter(/* 筛选条件 */);
const pagination = usePagination(filteredData, 10);
<DataPagination
{...pagination}
totalItems={filteredData.length}
/>
📊 组件 API
DataPagination Props
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| currentPage | number | ✅ | - | 当前页码 |
| totalPages | number | ✅ | - | 总页数 |
| pageSize | number | ✅ | - | 每页数量 |
| totalItems | number | ✅ | - | 总数据量 |
| startIndex | number | ✅ | - | 当前页起始索引 |
| endIndex | number | ✅ | - | 当前页结束索引 |
| onPageChange | (page: number) => void | ✅ | - | 页码变更回调 |
| onPageSizeChange | (size: number) => void | ✅ | - | 每页数量变更回调 |
| canPreviousPage | boolean | ✅ | - | 是否可以上一页 |
| canNextPage | boolean | ✅ | - | 是否可以下一页 |
| pageSizeOptions | number[] | ❌ | [10, 20, 50, 100] | 每页数量选项 |
usePagination Hook
const pagination = usePagination<T>(data: T[], initialPageSize?: number)
返回值:
{
currentPage: number; // 当前页码
pageSize: number; // 每页数量
totalPages: number; // 总页数
paginatedData: T[]; // 当前页数据
goToPage: (page: number) => void; // 跳转页码
nextPage: () => void; // 下一页
previousPage: () => void; // 上一页
setPageSize: (size: number) => void; // 设置每页数量
canPreviousPage: boolean; // 是否可上一页
canNextPage: boolean; // 是否可下一页
startIndex: number; // 起始索引
endIndex: number; // 结束索引
}
🎓 学习资源
相关文档
- 分页使用: 本文档
- 任务管理:
/TASK_TERMINATE_UPDATE.md - 列表组件: 各组件目录下的 README
示例代码
- 农机列表:
/components/machinery/MachineryList.tsx - 驾驶员列表:
/components/machinery/driver/DriverList.tsx - 任务列表:
/components/machinery/driver/DriverTask.tsx - 地块列表:
/components/field/FieldList.tsx
✅ 验证清单
视觉验证
- 分页组件在 Card 内部正确显示
- 顶部边框清晰可见
- 所有按钮大小一致 (9x9)
- 当前页绿色高亮
- 禁用按钮呈灰色
功能验证
- 点击页码正确跳转
- 上一页/下一页功能正常
- 第一页/最后页快捷键有效(桌面端)
- 更改每页数量后重置到第1页
- 筛选后分页正确更新
响应式验证
- 移动端垂直堆叠布局
- 桌面端水平排列布局
- 移动端隐藏快捷按钮
- 桌面端显示完整信息
- 各断点过渡流畅
边界验证
- 数据为空时不显示分页
- 只有1页时禁用导航按钮
- 第1页时禁用上一页
- 最后页时禁用下一页
- 总页数变化时正确更新
🎉 总结
本次分页组件优化带来了全面的改进:
核心改进
✅ 视觉统一 - 绿色主题,尺寸一致,布局规范
✅ 功能完善 - 4个导航按钮,快速跳转
✅ 响应式优化 - 移动/桌面端自适应
✅ 用户体验 - 清晰的当前页标识,完整的统计信息
技术亮点
✅ 组件化设计 - 独立的分页组件,易于复用
✅ TypeScript支持 - 完整的类型定义
✅ 性能优化 - useMemo 缓存分页数据
✅ 可扩展性 - 灵活的配置选项
现在,分页组件不仅美观大方,而且功能强大,为整个系统的列表展示提供了统一、流畅的用户体验!🎊
更新人: AI助手
更新日期: 2025-10-16
版本: v2.0
影响范围: 全系统分页组件