373 lines
8.7 KiB
Markdown
373 lines
8.7 KiB
Markdown
# API 直接导入重构说明
|
||
|
||
## 📋 重构内容
|
||
|
||
### 重构目标
|
||
|
||
将框架中的 API server 从**注入模式**改为**直接导入模式**,简化代码结构。
|
||
|
||
### 修改前(注入模式)
|
||
|
||
**问题**:
|
||
- 需要在 `src/index.js` 中调用 `setUserServer` 和 `setParamSetupServer`
|
||
- Store 模块需要导出 setter 函数
|
||
- 代码结构复杂,不够直观
|
||
|
||
**代码示例**:
|
||
```javascript
|
||
// src/store/user.js
|
||
let userServerInstance = null
|
||
|
||
export const setUserServer = (server) => {
|
||
userServerInstance = server
|
||
}
|
||
|
||
// 使用时
|
||
if (!userServerInstance) {
|
||
throw new Error('userServer not initialized')
|
||
}
|
||
let res = await userServerInstance.login(userFrom)
|
||
```
|
||
|
||
```javascript
|
||
// src/index.js
|
||
import { setUserServer } from './store/user'
|
||
import { setParamSetupServer } from './store/app'
|
||
import * as systemApi from './api/system'
|
||
import * as systemHighApi from './api/system_high'
|
||
|
||
// 自动设置 API
|
||
setUserServer(systemApi.userServer)
|
||
setParamSetupServer(systemHighApi.paramSetupServer)
|
||
```
|
||
|
||
### 修改后(直接导入模式)
|
||
|
||
**优点**:
|
||
- ✅ 代码更简洁
|
||
- ✅ 不需要额外的 setter 函数
|
||
- ✅ 依赖关系更清晰
|
||
- ✅ 符合 ES6 模块化规范
|
||
|
||
**代码示例**:
|
||
```javascript
|
||
// src/store/user.js
|
||
import userServer from '../api/system/userServer'
|
||
|
||
// 直接使用
|
||
let res = await userServer.login(userFrom)
|
||
```
|
||
|
||
```javascript
|
||
// src/index.js
|
||
// 不再需要 setUserServer 和 setParamSetupServer
|
||
import * as systemApi from './api/system'
|
||
import * as systemHighApi from './api/system_high'
|
||
```
|
||
|
||
## 📁 修改的文件
|
||
|
||
### 1. `src/store/user.js`
|
||
|
||
**修改前**:
|
||
```javascript
|
||
import { setToken, getToken } from '../utils/tools'
|
||
import uiTool from '../utils/uiTool'
|
||
import { defaultMenus, filterMenusByIds } from '../config/menuConfig'
|
||
|
||
// 注意:这里的 userServer 需要在使用时注入
|
||
let userServerInstance = null
|
||
|
||
export const setUserServer = (server) => {
|
||
userServerInstance = server
|
||
}
|
||
|
||
// 使用时
|
||
if (!userServerInstance) {
|
||
throw new Error('userServer not initialized')
|
||
}
|
||
let res = await userServerInstance.login(userFrom)
|
||
```
|
||
|
||
**修改后**:
|
||
```javascript
|
||
import { setToken, getToken } from '../utils/tools'
|
||
import uiTool from '../utils/uiTool'
|
||
import { defaultMenus, filterMenusByIds } from '../config/menuConfig'
|
||
import userServer from '../api/system/userServer'
|
||
|
||
// 直接使用
|
||
let res = await userServer.login(userFrom)
|
||
```
|
||
|
||
**变更点**:
|
||
- ✅ 移除了 `userServerInstance` 变量
|
||
- ✅ 移除了 `setUserServer` 导出函数
|
||
- ✅ 直接导入 `userServer`
|
||
- ✅ 移除了 `if (!userServerInstance)` 检查
|
||
- ✅ 将所有 `userServerInstance` 替换为 `userServer`
|
||
|
||
### 2. `src/store/app.js`
|
||
|
||
**修改前**:
|
||
```javascript
|
||
import { getBreadCrumbList, getHomeRoute } from '../utils/tools'
|
||
|
||
// 注意:这里的 paramSetupServer 需要在使用时注入
|
||
let paramSetupServerInstance = null
|
||
|
||
export const setParamSetupServer = (server) => {
|
||
paramSetupServerInstance = server
|
||
}
|
||
|
||
// 使用时
|
||
if (!paramSetupServerInstance) {
|
||
commit('setSysTitle', formModel)
|
||
return
|
||
}
|
||
let res1 = await paramSetupServerInstance.getOne('sys_title')
|
||
```
|
||
|
||
**修改后**:
|
||
```javascript
|
||
import { getBreadCrumbList, getHomeRoute } from '../utils/tools'
|
||
import paramSetupServer from '../api/system_high/paramSetupServer'
|
||
|
||
// 直接使用
|
||
let res1 = await paramSetupServer.getOne('sys_title')
|
||
```
|
||
|
||
**变更点**:
|
||
- ✅ 移除了 `paramSetupServerInstance` 变量
|
||
- ✅ 移除了 `setParamSetupServer` 导出函数
|
||
- ✅ 直接导入 `paramSetupServer`
|
||
- ✅ 移除了 `if (!paramSetupServerInstance)` 检查
|
||
- ✅ 将所有 `paramSetupServerInstance` 替换为 `paramSetupServer`
|
||
|
||
### 3. `src/index.js`
|
||
|
||
**修改前**:
|
||
```javascript
|
||
// ==================== Store 模块 ====================
|
||
import storeModules, { userModule, appModule } from './store'
|
||
import { setUserServer } from './store/user'
|
||
import { setParamSetupServer } from './store/app'
|
||
|
||
// ==================== 系统 API ====================
|
||
import * as systemApi from './api/system'
|
||
import * as systemHighApi from './api/system_high'
|
||
|
||
// 自动设置 API
|
||
setUserServer(systemApi.userServer)
|
||
setParamSetupServer(systemHighApi.paramSetupServer)
|
||
|
||
// AdminFramework 类中的方法
|
||
class AdminFramework {
|
||
/**
|
||
* 设置用户服务实例
|
||
*/
|
||
setUserServer(userServer) {
|
||
setUserServer(userServer)
|
||
}
|
||
|
||
/**
|
||
* 设置参数设置服务实例
|
||
*/
|
||
setParamSetupServer(paramSetupServer) {
|
||
setParamSetupServer(paramSetupServer)
|
||
}
|
||
}
|
||
```
|
||
|
||
**修改后**:
|
||
```javascript
|
||
// ==================== Store 模块 ====================
|
||
import storeModules, { userModule, appModule } from './store'
|
||
|
||
// ==================== 系统 API ====================
|
||
import * as systemApi from './api/system'
|
||
import * as systemHighApi from './api/system_high'
|
||
|
||
// AdminFramework 类中移除了 setUserServer 和 setParamSetupServer 方法
|
||
```
|
||
|
||
**变更点**:
|
||
- ✅ 移除了 `setUserServer` 和 `setParamSetupServer` 的导入
|
||
- ✅ 移除了自动设置 API 的代码
|
||
- ✅ 移除了 `AdminFramework` 类中的 `setUserServer` 和 `setParamSetupServer` 方法
|
||
|
||
## 🎯 影响范围
|
||
|
||
### 不受影响的功能
|
||
|
||
- ✅ 登录功能
|
||
- ✅ 权限菜单
|
||
- ✅ 系统标题
|
||
- ✅ 所有业务功能
|
||
|
||
### 代码简化
|
||
|
||
**减少的代码行数**:
|
||
- `src/store/user.js`: -7 行
|
||
- `src/store/app.js`: -7 行
|
||
- `src/index.js`: -12 行
|
||
- **总计**: -26 行
|
||
|
||
**移除的概念**:
|
||
- ❌ `userServerInstance` 变量
|
||
- ❌ `paramSetupServerInstance` 变量
|
||
- ❌ `setUserServer` 函数
|
||
- ❌ `setParamSetupServer` 函数
|
||
- ❌ API 注入机制
|
||
|
||
## 📊 对比表
|
||
|
||
| 特性 | 注入模式 | 直接导入模式 |
|
||
|------|---------|------------|
|
||
| 代码行数 | 多 | 少 |
|
||
| 复杂度 | 高 | 低 |
|
||
| 依赖关系 | 隐式 | 显式 |
|
||
| 初始化检查 | 需要 | 不需要 |
|
||
| 灵活性 | 高(可运行时替换) | 中(编译时确定) |
|
||
| 可读性 | 中 | 高 |
|
||
| 维护性 | 中 | 高 |
|
||
|
||
## 💡 设计理念
|
||
|
||
### 为什么选择直接导入?
|
||
|
||
1. **简单性优先**
|
||
- 对于大多数项目,API server 是固定的
|
||
- 不需要运行时动态替换
|
||
- 直接导入更符合直觉
|
||
|
||
2. **符合 ES6 规范**
|
||
- 使用标准的 `import` 语法
|
||
- 依赖关系在文件顶部清晰可见
|
||
- 便于静态分析和 tree-shaking
|
||
|
||
3. **减少样板代码**
|
||
- 不需要额外的 setter 函数
|
||
- 不需要初始化检查
|
||
- 代码更简洁
|
||
|
||
### 何时使用注入模式?
|
||
|
||
如果你的项目需要以下特性,可以考虑使用注入模式:
|
||
|
||
1. **运行时替换 API**
|
||
- 例如:测试环境使用 mock API
|
||
- 例如:多租户系统使用不同的 API
|
||
|
||
2. **插件化架构**
|
||
- 框架作为独立包发布
|
||
- 使用者可以自定义 API 实现
|
||
|
||
3. **依赖注入容器**
|
||
- 使用 IoC 容器管理依赖
|
||
- 需要复杂的依赖管理
|
||
|
||
对于本项目,直接导入模式更合适。
|
||
|
||
## 🧪 测试验证
|
||
|
||
### 测试步骤
|
||
|
||
1. **启动项目**
|
||
```bash
|
||
cd demo-project
|
||
npm run dev
|
||
```
|
||
|
||
2. **测试登录**
|
||
- 访问 `http://localhost:8080`
|
||
- 输入用户名密码
|
||
- 点击登录
|
||
|
||
3. **验证功能**
|
||
- ✅ 登录成功
|
||
- ✅ 菜单显示正常
|
||
- ✅ 系统标题显示正常
|
||
- ✅ 页面跳转正常
|
||
|
||
### 预期结果
|
||
|
||
所有功能正常工作,与重构前完全一致。
|
||
|
||
## 📝 迁移指南
|
||
|
||
如果你的项目使用了旧的注入模式,可以按以下步骤迁移:
|
||
|
||
### 步骤 1:修改 Store 模块
|
||
|
||
**user.js**:
|
||
```javascript
|
||
// 删除
|
||
let userServerInstance = null
|
||
export const setUserServer = (server) => {
|
||
userServerInstance = server
|
||
}
|
||
|
||
// 添加
|
||
import userServer from '../api/system/userServer'
|
||
|
||
// 替换所有 userServerInstance 为 userServer
|
||
```
|
||
|
||
**app.js**:
|
||
```javascript
|
||
// 删除
|
||
let paramSetupServerInstance = null
|
||
export const setParamSetupServer = (server) => {
|
||
paramSetupServerInstance = server
|
||
}
|
||
|
||
// 添加
|
||
import paramSetupServer from '../api/system_high/paramSetupServer'
|
||
|
||
// 替换所有 paramSetupServerInstance 为 paramSetupServer
|
||
```
|
||
|
||
### 步骤 2:修改 index.js
|
||
|
||
```javascript
|
||
// 删除这些导入
|
||
import { setUserServer } from './store/user'
|
||
import { setParamSetupServer } from './store/app'
|
||
|
||
// 删除这些调用
|
||
setUserServer(systemApi.userServer)
|
||
setParamSetupServer(systemHighApi.paramSetupServer)
|
||
|
||
// 删除 AdminFramework 类中的这些方法
|
||
setUserServer(userServer) { ... }
|
||
setParamSetupServer(paramSetupServer) { ... }
|
||
```
|
||
|
||
### 步骤 3:测试验证
|
||
|
||
运行项目,确保所有功能正常。
|
||
|
||
## ✅ 总结
|
||
|
||
### 重构成果
|
||
|
||
- ✅ 代码更简洁(减少 26 行)
|
||
- ✅ 结构更清晰
|
||
- ✅ 依赖关系更明确
|
||
- ✅ 维护更容易
|
||
- ✅ 功能完全正常
|
||
|
||
### 后续建议
|
||
|
||
1. **保持简单**:除非有特殊需求,否则使用直接导入
|
||
2. **统一风格**:项目中的所有 API 都使用相同的导入方式
|
||
3. **文档更新**:更新项目文档,说明 API 的使用方式
|
||
|
||
---
|
||
|
||
**重构完成!** 🎉
|
||
|
||
现在框架代码更简洁、更易维护了。
|
||
|