@@ -1,187 +0,0 @@
|
||||
# 分页组件重构总结
|
||||
|
||||
## 🎯 重构目标
|
||||
|
||||
通过创建 `usePagination` composable 来减少项目中分页相关的重复代码,统一分页逻辑。
|
||||
|
||||
## 📋 已完成的更新
|
||||
|
||||
### 1. 核心 Composable
|
||||
- ✅ **创建 `usePagination` composable** (`/shared/composables/pagination.ts`)
|
||||
- 自动处理分页状态管理(页码、每页条数)
|
||||
- 自动同步 URL 查询参数
|
||||
- 支持自定义查询条件
|
||||
- 提供便捷的清空、重置方法
|
||||
- 完整的 TypeScript 类型支持
|
||||
|
||||
### 2. 前台用户页面
|
||||
- ✅ **问题列表页** (`/oj/problem/list.vue`)
|
||||
- 移除 25+ 行重复代码
|
||||
- 简化查询逻辑
|
||||
- 保留防抖搜索功能
|
||||
|
||||
- ✅ **提交记录页** (`/oj/submission/list.vue`)
|
||||
- 简化复杂的查询条件处理
|
||||
- 统一 URL 同步逻辑
|
||||
- 保留所有筛选功能
|
||||
|
||||
- ✅ **比赛列表页** (`/oj/contest/list.vue`)
|
||||
- 减少路由处理代码
|
||||
- 统一分页行为
|
||||
|
||||
### 3. 管理员页面
|
||||
- ✅ **用户管理页** (`/admin/user/list.vue`)
|
||||
- 简化用户查询和筛选逻辑
|
||||
- 统一分页处理
|
||||
|
||||
- ✅ **题目管理页** (`/admin/problem/list.vue`)
|
||||
- 减少重复的路由同步代码
|
||||
- 保留题目搜索功能
|
||||
|
||||
## 📊 重构效果
|
||||
|
||||
### 代码减少统计
|
||||
- **每个页面减少代码量**: 20-30 行
|
||||
- **总计减少代码量**: 约 150+ 行
|
||||
- **重复逻辑消除**: 100%
|
||||
|
||||
### 重构前后对比
|
||||
|
||||
#### 重构前(每个分页页面都需要)
|
||||
```vue
|
||||
<script setup>
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const query = reactive({
|
||||
page: parseInt(route.query.page) || 1,
|
||||
limit: parseInt(route.query.limit) || 10,
|
||||
keyword: route.query.keyword ?? "",
|
||||
// ... 其他查询条件
|
||||
})
|
||||
|
||||
function routerPush() {
|
||||
router.push({
|
||||
path: route.path,
|
||||
query: filterEmptyValue(query),
|
||||
})
|
||||
}
|
||||
|
||||
async function loadData() {
|
||||
// 从 URL 同步状态
|
||||
query.keyword = route.query.keyword ?? ""
|
||||
query.page = parseInt(route.query.page) || 1
|
||||
query.limit = parseInt(route.query.limit) || 10
|
||||
// ... 其他同步逻辑
|
||||
|
||||
// API 调用
|
||||
const res = await api.getData(...)
|
||||
}
|
||||
|
||||
// 大量的 watch 逻辑
|
||||
watch(() => query.page, routerPush)
|
||||
watch(() => [query.limit, /* 其他条件 */], () => {
|
||||
query.page = 1
|
||||
routerPush()
|
||||
})
|
||||
watchDebounced(() => query.keyword, () => {
|
||||
query.page = 1
|
||||
routerPush()
|
||||
}, { debounce: 500 })
|
||||
</script>
|
||||
```
|
||||
|
||||
#### 重构后(简洁高效)
|
||||
```vue
|
||||
<script setup>
|
||||
// 一行代码完成所有分页逻辑
|
||||
const { query, clearQuery } = usePagination({
|
||||
keyword: "",
|
||||
// ... 其他查询条件
|
||||
})
|
||||
|
||||
async function loadData() {
|
||||
// 直接使用 query,无需同步逻辑
|
||||
const res = await api.getData({
|
||||
offset: (query.page - 1) * query.limit,
|
||||
limit: query.limit,
|
||||
keyword: query.keyword,
|
||||
})
|
||||
}
|
||||
|
||||
// 简化的监听逻辑
|
||||
watchDebounced(() => query.keyword, loadData, { debounce: 500 })
|
||||
watch(() => [query.page, query.limit], loadData)
|
||||
</script>
|
||||
```
|
||||
|
||||
## 🚀 主要优势
|
||||
|
||||
### 1. 代码复用性
|
||||
- 所有分页逻辑集中管理
|
||||
- 统一的行为模式
|
||||
- 减少维护成本
|
||||
|
||||
### 2. 类型安全
|
||||
- 完整的 TypeScript 支持
|
||||
- 自定义查询条件的类型推导
|
||||
- 编译时错误检查
|
||||
|
||||
### 3. 自动化处理
|
||||
- 自动 URL 同步
|
||||
- 自动页码重置
|
||||
- 自动路由监听
|
||||
- 浏览器前进后退支持
|
||||
|
||||
### 4. 灵活配置
|
||||
- 可自定义默认值
|
||||
- 可选择重置行为
|
||||
- 支持复杂查询条件
|
||||
|
||||
## 🔧 使用方法
|
||||
|
||||
### 基本用法
|
||||
```typescript
|
||||
const { query } = usePagination()
|
||||
// query.page, query.limit 自动可用
|
||||
```
|
||||
|
||||
### 带查询条件
|
||||
```typescript
|
||||
const { query, clearQuery } = usePagination({
|
||||
keyword: "",
|
||||
status: "",
|
||||
category: "",
|
||||
})
|
||||
```
|
||||
|
||||
### 配置选项
|
||||
```typescript
|
||||
const { query } = usePagination(
|
||||
{ keyword: "" },
|
||||
{
|
||||
defaultLimit: 20,
|
||||
defaultPage: 1,
|
||||
resetPageOnChange: true,
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## 📝 迁移指南
|
||||
|
||||
1. 导入 `usePagination`
|
||||
2. 替换原有的 `query` 定义
|
||||
3. 移除 `routerPush` 函数
|
||||
4. 简化 `watch` 逻辑
|
||||
5. 更新 `clear` 函数使用 `clearQuery`
|
||||
|
||||
## 🎉 总结
|
||||
|
||||
这次重构成功地:
|
||||
- **大幅减少了重复代码**(每个页面减少 20-30 行)
|
||||
- **统一了分页行为**(所有页面行为一致)
|
||||
- **提升了开发效率**(新页面只需 1 行代码即可获得完整分页功能)
|
||||
- **增强了类型安全**(完整的 TypeScript 支持)
|
||||
- **保持了组件纯净性**(Pagination.vue 组件职责单一)
|
||||
|
||||
通过这个 composable,未来添加新的分页页面将变得非常简单,只需要一行代码就能获得完整的分页功能。
|
||||
Reference in New Issue
Block a user