220 lines
4.6 KiB
Markdown
220 lines
4.6 KiB
Markdown
# 数据管理 Mixin 重构说明
|
||
|
||
## 问题分析
|
||
|
||
原来的 `data-manager.js` 存在以下复用性问题:
|
||
|
||
1. **硬编码的响应结构**:假设所有API都返回 `response.rows` 格式
|
||
2. **固定的分页参数**:只能传递 `pageNum` 和 `pageSize`,无法处理复杂查询条件
|
||
3. **缺乏灵活性**:无法处理搜索、筛选等场景
|
||
4. **错误处理过于简单**:统一的错误提示可能不适合所有场景
|
||
5. **缺乏扩展性**:难以添加缓存、状态管理等功能
|
||
|
||
## 重构改进
|
||
|
||
### 1. 灵活的配置选项
|
||
|
||
```javascript
|
||
// 重构前
|
||
await this.fetchData(false, apiCall, dataTransformer)
|
||
|
||
// 重构后
|
||
await this.fetchData({
|
||
isLoadMore: false,
|
||
apiCall,
|
||
dataTransformer,
|
||
params: { keyword: '搜索词' },
|
||
dataPath: 'data.list.rows',
|
||
totalPath: 'data.total',
|
||
onSuccess: (data, response) => console.log('成功'),
|
||
onError: errorMsg => console.error('失败'),
|
||
showLoading: true,
|
||
showError: true,
|
||
})
|
||
```
|
||
|
||
### 2. 支持多种数据格式
|
||
|
||
```javascript
|
||
// 支持不同的响应结构
|
||
dataPath: 'data.list.rows' // 嵌套结构
|
||
dataPath: 'data' // 简单结构
|
||
dataPath: 'rows' // 直接结构
|
||
```
|
||
|
||
### 3. 增强的功能
|
||
|
||
- **搜索功能**:`searchData()` 方法
|
||
- **状态管理**:`getDataState()` 方法
|
||
- **分页重置**:`resetPagination()` 方法
|
||
- **参数管理**:自动保存当前查询参数
|
||
- **回调支持**:成功和失败回调函数
|
||
|
||
### 4. 更好的错误处理
|
||
|
||
```javascript
|
||
// 可配置是否显示错误提示
|
||
showError: false, // 自定义错误处理
|
||
onError: (errorMsg, response) => {
|
||
// 自定义错误处理逻辑
|
||
}
|
||
```
|
||
|
||
## 使用示例
|
||
|
||
### 基础使用
|
||
|
||
```javascript
|
||
import { dataManagerMixin } from './data-manager.js'
|
||
|
||
export default {
|
||
mixins: [dataManagerMixin],
|
||
|
||
methods: {
|
||
async loadData() {
|
||
await this.refreshData({
|
||
apiCall: this.getListAPI,
|
||
dataPath: 'data.list',
|
||
onSuccess: data => {
|
||
console.log('数据加载成功:', data.length)
|
||
},
|
||
})
|
||
},
|
||
},
|
||
}
|
||
```
|
||
|
||
### 带搜索的使用
|
||
|
||
```javascript
|
||
async searchData(keyword) {
|
||
await this.searchData(
|
||
{ keyword, status: 'active' },
|
||
{
|
||
apiCall: this.searchAPI,
|
||
dataPath: 'data.items',
|
||
onSuccess: (data) => {
|
||
console.log('搜索完成:', data.length)
|
||
}
|
||
}
|
||
)
|
||
}
|
||
```
|
||
|
||
### 加载更多
|
||
|
||
```javascript
|
||
async loadMore() {
|
||
await this.loadMoreData({
|
||
apiCall: this.getListAPI,
|
||
dataPath: 'data.list',
|
||
onSuccess: (data) => {
|
||
console.log('加载更多:', data.length)
|
||
}
|
||
})
|
||
}
|
||
```
|
||
|
||
## 高级功能
|
||
|
||
### 1. 缓存支持
|
||
|
||
```javascript
|
||
import { cachedDataMixin } from './data-manager-example.js'
|
||
|
||
export default {
|
||
mixins: [cachedDataMixin],
|
||
|
||
methods: {
|
||
async loadDataWithCache() {
|
||
await this.fetchDataWithCache({
|
||
apiCall: this.getListAPI,
|
||
params: { category: 'news' },
|
||
forceRefresh: false, // 使用缓存
|
||
})
|
||
},
|
||
},
|
||
}
|
||
```
|
||
|
||
### 2. 状态管理
|
||
|
||
```javascript
|
||
// 获取当前数据状态
|
||
const state = this.getDataState()
|
||
console.log('当前页码:', state.pageNum)
|
||
console.log('总数据量:', state.total)
|
||
console.log('查询参数:', state.currentParams)
|
||
```
|
||
|
||
### 3. 自定义数据转换
|
||
|
||
```javascript
|
||
transformData(dataArray) {
|
||
return dataArray.map(item => ({
|
||
id: item.id,
|
||
title: item.name,
|
||
date: this.formatDate(item.createTime),
|
||
status: item.status === 1 ? '启用' : '禁用'
|
||
}))
|
||
}
|
||
```
|
||
|
||
## 迁移指南
|
||
|
||
### 从旧版本迁移
|
||
|
||
1. **更新 mixin 引用**:
|
||
|
||
```javascript
|
||
// 旧版本
|
||
export const myMixin = {
|
||
// 直接定义分页逻辑
|
||
}
|
||
|
||
// 新版本
|
||
import { dataManagerMixin } from './data-manager.js'
|
||
export const myMixin = {
|
||
mixins: [dataManagerMixin],
|
||
// 使用通用的分页逻辑
|
||
}
|
||
```
|
||
|
||
2. **更新方法调用**:
|
||
|
||
```javascript
|
||
// 旧版本
|
||
await this.fetchData(false, apiCall, transformer)
|
||
|
||
// 新版本
|
||
await this.refreshData({
|
||
apiCall,
|
||
dataTransformer: transformer,
|
||
})
|
||
```
|
||
|
||
3. **更新数据引用**:
|
||
|
||
```javascript
|
||
// 旧版本
|
||
this.myList = []
|
||
|
||
// 新版本
|
||
// 使用 this.dataList (来自 dataManagerMixin)
|
||
```
|
||
|
||
## 优势总结
|
||
|
||
1. **高复用性**:一个 mixin 适用于所有列表页面
|
||
2. **强扩展性**:支持缓存、状态管理、自定义回调等
|
||
3. **易维护性**:统一的错误处理和状态管理
|
||
4. **灵活性**:支持多种数据格式和查询条件
|
||
5. **开发效率**:减少重复代码,提高开发速度
|
||
|
||
## 注意事项
|
||
|
||
1. 确保 API 返回格式包含 `code` 字段用于判断成功状态
|
||
2. 数据路径 `dataPath` 要根据实际 API 响应格式设置
|
||
3. 使用 `dataTransformer` 时注意保持数据结构的统一性
|
||
4. 合理使用缓存功能,避免内存泄漏
|