# 组件映射机制说明
## 🎯 问题原因
之前所有页面都显示 404 是因为:
- 后端返回的权限菜单包含组件路径(如 `"component": "system/sys_user.vue"`)
- 但框架没有将这些路径映射到实际组件
- 所有页面都被设置为 `Page404` 组件
## ✅ 解决方案
### 1. 框架内置组件映射
框架现在自动映射以下系统页面:
```javascript
// 框架自动映射的组件
{
'home/index': HomePage, // 主页
'system/sys_log': SysLog, // 日志管理
'system/sys_param_setup': SysParamSetup, // 参数设置
'system/sys_role': SysRole, // 角色管理
'system/sys_user': SysUser, // 用户管理
'system_high/sys_control': SysControl, // 控制器管理
'system_high/sys_menu': SysMenu, // 菜单管理
'system_high/sys_title': SysTitle // 系统标题设置
}
```
**自动支持**:
- ✅ `home/index` 和 `home/index.vue` 都能识别
- ✅ `system/sys_user` 和 `system/sys_user.vue` 都能识别
### 2. 添加自定义业务组件
在项目的 `main.js` 中添加自定义组件映射:
```javascript
import ProductList from './views/business/product_list.vue'
import GamesComponent from './views/ball/games.vue'
import PayOrdersComponent from './views/order/pay_orders.vue'
// 使用框架
Vue.use(AdminFramework, { config, ViewUI, VueRouter, Vuex, createPersistedState })
// 添加自定义组件映射
AdminFramework.addComponentMap({
'business/product_list.vue': ProductList,
'ball/games.vue': GamesComponent,
'order/pay_orders.vue': PayOrdersComponent
})
```
**说明**:
- 只需要添加 `.vue` 后缀的映射
- 框架会自动处理不带后缀的路径
### 3. 权限菜单格式
后端返回的菜单格式:
```json
{
"code": 0,
"data": [
{
"id": 1,
"name": "首页",
"path": "home",
"component": "home/index.vue", ← 这个路径会自动映射到 HomePage 组件
"type": "页面"
},
{
"id": 11,
"name": "系统用户",
"path": "sys_user",
"component": "system/sys_user.vue", ← 映射到 SysUser 组件
"type": "页面"
},
{
"id": 123,
"name": "球局表",
"path": "games",
"component": "ball/games.vue", ← 需要在项目中添加映射
"type": "页面"
}
]
}
```
## 🔧 完整示例
### demo-project/src/main.js
```javascript
import Vue from 'vue'
import VueRouter from 'vue-router'
import Vuex from 'vuex'
import ViewUI from 'view-design'
import createPersistedState from 'vuex-persistedstate'
import 'view-design/dist/styles/iview.css'
import AdminFramework from '../../src/index.js'
import config from './config'
import App from './App.vue'
// 引入业务组件
import ProductList from './views/business/product_list.vue'
// import GamesComponent from './views/ball/games.vue'
// import PayOrdersComponent from './views/order/pay_orders.vue'
// 使用框架
Vue.use(AdminFramework, {
config,
ViewUI,
VueRouter,
Vuex,
createPersistedState
})
// 添加业务组件映射
AdminFramework.addComponentMap({
'business/product_list.vue': ProductList
// 'ball/games.vue': GamesComponent,
// 'order/pay_orders.vue': PayOrdersComponent
})
// 创建 Vue 实例
new Vue({
el: '#app',
router: AdminFramework.router,
store: AdminFramework.store,
render: h => h(App),
mounted() {
AdminFramework.uiTool.setRem()
// 设置权限菜单(会自动根据映射表加载组件)
this.$store.dispatch('user/setAuthorityMenus', {
Main: AdminFramework.Main,
ParentView: AdminFramework.ParentView,
Page404: AdminFramework.Page404
})
}
})
```
## 📋 映射机制
### 1. 框架自动映射
框架在 `install` 时自动映射系统组件:
```javascript
Vue.use(AdminFramework, { ... })
// ↓ 自动执行
setupComponentMap()
// ↓ 映射系统页面
{
'home/index': HomePage,
'home/index.vue': HomePage,
'system/sys_user': SysUser,
'system/sys_user.vue': SysUser,
// ...
}
```
### 2. 用户添加映射
用户可以添加自定义业务组件映射:
```javascript
AdminFramework.addComponentMap({
'ball/games.vue': GamesComponent
})
// ↓ 添加到映射表
{
...已有映射,
'ball/games.vue': GamesComponent
}
```
### 3. 路由生成
当调用 `setAuthorityMenus` 时:
```javascript
// 后端返回菜单
[
{ component: "system/sys_user.vue", ... }
]
// ↓ menuToRoute 处理
// ↓ 从映射表获取组件
component: SysUser // ✅ 找到对应组件
```
## ⚠️ 未找到组件的处理
如果后端返回的组件路径在映射表中不存在:
```javascript
// 显示占位组件
component: {
render: h => h('div', [
h('Alert', { type: 'warning' }, [
h('p', '页面组件未加载: ball/games.vue'),
h('p', '请在项目中创建此组件或在组件映射表中注册')
])
])
}
```
**控制台警告**:
```
⚠️ 组件未找到: ball/games.vue,使用占位组件
```
## 💡 最佳实践
### 1. 框架内置页面
直接使用,无需配置:
- `home/index.vue` - 主页
- `system/sys_user.vue` - 用户管理
- `system/sys_role.vue` - 角色管理
- `system/sys_log.vue` - 日志管理
- `system/sys_param_setup.vue` - 参数设置
- `system_high/sys_menu.vue` - 菜单管理
- `system_high/sys_control.vue` - 控制器管理
- `system_high/sys_title.vue` - 系统标题设置
### 2. 自定义业务页面
在 main.js 中添加映射:
```javascript
// 1. 导入组件
import GamesComponent from './views/ball/games.vue'
// 2. 添加映射
AdminFramework.addComponentMap({
'ball/games.vue': GamesComponent
})
```
### 3. 路径命名建议
保持后端返回的路径与实际文件路径一致:
```
后端:component: "ball/games.vue"
项目:src/views/ball/games.vue
```
## 📊 代码优化对比
### 优化前(重复代码)
```javascript
const map = {
'system/sys_user.vue': SysUser,
'system/sys_user': SysUser, // 重复
'system/sys_role.vue': SysRole,
'system/sys_role': SysRole, // 重复
'system/sys_log.vue': SysLog,
'system/sys_log': SysLog, // 重复
// 每个组件写两遍...
}
```
### 优化后(自动生成)
```javascript
const components = {
'system/sys_user': SysUser,
'system/sys_role': SysRole,
'system/sys_log': SysLog
}
// 自动生成带 .vue 和不带 .vue 的映射
const map = {}
Object.keys(components).forEach(path => {
map[path] = components[path]
map[path + '.vue'] = components[path]
})
```
**优势**:
- ✅ 代码量减少 50%
- ✅ 易于维护
- ✅ 不易出错
## 🚀 使用方法
### 步骤 1:创建业务组件
在项目中创建组件文件:
```vue
球局管理页面
```
### 步骤 2:添加组件映射
在 `src/main.js` 中:
```javascript
import GamesComponent from './views/ball/games.vue'
AdminFramework.addComponentMap({
'ball/games.vue': GamesComponent
})
```
### 步骤 3:后端返回菜单
确保后端菜单中的路径正确:
```json
{
"component": "ball/games.vue",
"path": "games"
}
```
### 步骤 4:自动生成路由
框架会自动将菜单转换为路由,并加载对应组件!
## 📚 相关文档
- [README.md](./README.md) - 项目说明
- [CHANGELOG.md](./CHANGELOG.md) - 更新日志
- [../完整使用文档.md](../完整使用文档.md) - 框架完整文档
---
**现在启动项目,权限菜单中的系统页面都能正常显示了!** 🎉
对于业务页面(ball/games.vue, order/pay_orders.vue 等),只需:
1. 在项目中创建对应组件
2. 在 main.js 中添加组件映射