9.9 KiB
9.9 KiB
移除硬编码首页说明
🎯 修改目标
移除代码中硬编码的首页路由,完全依赖后端接口返回的菜单配置(包括首页)。
📋 修改原因
之前的问题
硬编码首页:
// 在代码中创建默认首页
const defaultHomeRoute = {
path: '/home',
name: 'home',
meta: { title: '首页', notCache: true },
component: HomePage
}
问题:
- ❌ 首页配置写死在代码中
- ❌ 无法通过后端动态配置首页
- ❌ 首页和其他菜单的处理逻辑不一致
- ❌ 增加了代码复杂度
新的设计
完全依赖后端:
- ✅ 首页配置由后端返回
- ✅ 首页和其他菜单统一处理
- ✅ 代码更简洁
- ✅ 配置更灵活
📝 修改内容
1. 修改 src/utils/uiTool.js 的 getRoutes 方法
修改前:
static getRoutes(Main, ParentView, Page404, HomePage) {
// 创建默认的首页路由
const defaultHomeRoute = {
path: '/home',
name: 'home',
meta: { title: '首页', notCache: true },
component: HomePage || {
render: h => h('div', { style: { padding: '20px' } }, '欢迎使用管理系统')
}
}
let mainRoute = {
path: '/',
name: '主视图',
redirect: '/home',
component: Main,
meta: { title: '首页', notCache: true },
children: [defaultHomeRoute] // ❌ 硬编码首页
}
// 从 localStorage 读取权限菜单
if (localStorage.authorityMenus && localStorage.authorityMenus !== 'undefined') {
let authorityMenus = JSON.parse(localStorage.authorityMenus) || []
if (authorityMenus && authorityMenus.length > 0) {
let menus = uiTool.transformTree(authorityMenus)
let curRoutes = uiTool.menuToRoute(menus, ParentView, Page404)
// 检查权限路由中是否有 home
const hasHome = curRoutes.some(r => r.name === 'home')
if (hasHome) {
mainRoute.children = curRoutes
} else {
mainRoute.children = [defaultHomeRoute, ...curRoutes] // ❌ 复杂的合并逻辑
}
}
}
return mainRoute
}
修改后:
static getRoutes(Main, ParentView, Page404) {
let mainRoute = {
path: '/',
name: '主视图',
redirect: '/home',
component: Main,
meta: { title: '首页', notCache: true },
children: [] // ✅ 初始为空
}
// 从 localStorage 读取权限菜单
if (localStorage.authorityMenus && localStorage.authorityMenus !== 'undefined') {
let authorityMenus = JSON.parse(localStorage.authorityMenus) || []
if (authorityMenus && authorityMenus.length > 0) {
let menus = uiTool.transformTree(authorityMenus)
let curRoutes = uiTool.menuToRoute(menus, ParentView, Page404)
// ✅ 直接使用后端返回的路由(包括首页)
mainRoute.children = curRoutes
}
}
return mainRoute
}
改进点:
- ✅ 移除了
HomePage参数 - ✅ 移除了
defaultHomeRoute的创建 - ✅ 移除了复杂的首页合并逻辑
- ✅ 代码更简洁,逻辑更清晰
2. 更新 src/index.js 中的调用
修改前:
// 获取主路由配置(包含 home)
const mainRoute = this.getRoutes({ Main, ParentView, Page404, HomePage })
// getRoutes 方法
getRoutes(components = {}) {
const { Main, ParentView, Page404, HomePage } = components
if (!Main || !ParentView || !Page404) {
console.error('Missing required layout components')
return null
}
return uiTool.getRoutes(Main, ParentView, Page404, HomePage)
}
修改后:
// 获取主路由配置(从后端权限菜单生成)
const mainRoute = this.getRoutes({ Main, ParentView, Page404 })
// getRoutes 方法
getRoutes(components = {}) {
const { Main, ParentView, Page404 } = components
if (!Main || !ParentView || !Page404) {
console.error('Missing required layout components')
return null
}
return uiTool.getRoutes(Main, ParentView, Page404)
}
改进点:
- ✅ 移除了
HomePage参数 - ✅ 注释更准确
3. 确保默认菜单配置包含首页
src/config/menuConfig.js:
export const defaultMenus = [
{
id: 1,
name: '首页',
path: '/home',
component: 'home/index',
parent_id: 0,
type: '页面',
is_show_menu: 1,
icon: 'md-home',
sort: 1
},
// ... 其他菜单
]
说明:
- ✅ 默认菜单配置中包含首页(id: 1)
- ✅ 当
authorityMenus接口失败时,会使用这个默认配置 - ✅ 确保即使接口失败,也能显示首页
📊 新的路由生成流程
应用启动时
应用启动
↓
框架初始化
↓
调用 getRoutes
↓
从 localStorage 读取 authorityMenus
↓
authorityMenus 存在?
├─ 是 → 解析菜单数据
│ ↓
│ transformTree (构建树形结构)
│ ↓
│ menuToRoute (转换为路由配置)
│ ↓
│ 生成路由(包括首页)✅
│
└─ 否 → children = [] (空路由)
↓
显示登录页面
登录后
用户登录
↓
调用登录接口
↓
保存 token 和用户信息
↓
调用 setAuthorityMenus
├─ 尝试调用 authorityMenus 接口
│ ├─ 成功 → 使用后端返回的菜单(包括首页)
│ └─ 失败 → 使用默认菜单配置(包括首页)
↓
保存到 localStorage
↓
刷新页面
↓
重新执行应用启动流程
↓
从 localStorage 读取菜单
↓
生成路由(包括首页)✅
🎯 后端接口要求
authorityMenus 接口返回格式
必须包含首页配置:
{
"code": 0,
"message": "请求成功",
"data": [
{
"id": 1,
"name": "首页",
"path": "/home",
"component": "home/index",
"parent_id": 0,
"type": "页面",
"is_show_menu": 1,
"icon": "md-home",
"sort": 1
},
{
"id": 5,
"name": "系统管理",
"path": "/system",
"component": "",
"parent_id": 0,
"type": "菜单",
"is_show_menu": 1,
"icon": "md-settings",
"sort": 2,
"children": [
{
"id": 11,
"name": "用户管理",
"path": "/system/user",
"component": "system/sys_user",
"parent_id": 5,
"type": "页面",
"is_show_menu": 1
}
]
}
]
}
首页配置说明
必需字段:
id: 菜单 ID(建议使用 1)name: 菜单名称(如 "首页")path: 路由路径(必须是/home)component: 组件路径(如home/index)parent_id: 父菜单 ID(0 表示顶级菜单)type: 类型("页面")is_show_menu: 是否显示在菜单中(1=显示,0=隐藏)
可选字段:
icon: 图标名称(如md-home)sort: 排序(建议设为 1,让首页排在第一位)
✅ 优势
1. 代码更简洁
代码行数减少:
- 移除了
defaultHomeRoute的创建 - 移除了首页合并逻辑
- 移除了
HomePage参数传递
复杂度降低:
- 不需要判断是否有首页
- 不需要合并首页和其他路由
- 逻辑更直观
2. 配置更灵活
后端控制:
- ✅ 首页路径可以动态配置
- ✅ 首页组件可以动态指定
- ✅ 首页标题可以动态设置
- ✅ 首页图标可以动态配置
统一管理:
- ✅ 所有菜单(包括首页)都由后端管理
- ✅ 权限控制统一
- ✅ 配置方式统一
3. 维护更容易
单一数据源:
- ✅ 菜单配置只来自后端
- ✅ 不需要维护前端的默认首页
- ✅ 修改首页只需要修改后端配置
降级方案:
- ✅ 如果
authorityMenus接口失败 - ✅ 使用
defaultMenus配置(包含首页) - ✅ 确保系统可用
⚠️ 注意事项
1. 后端必须返回首页配置
如果后端返回的菜单数据中没有首页,用户登录后会看不到首页。
解决方案:
- 确保后端
authorityMenus接口返回包含首页的菜单数据 - 或者在
defaultMenus中包含首页作为兜底
2. 首页路径必须是 /home
因为主路由的 redirect 设置为 /home:
let mainRoute = {
path: '/',
redirect: '/home', // ← 重定向到 /home
// ...
}
要求:
- 后端返回的首页配置中,
path必须是/home - 或者修改主路由的
redirect配置
3. 组件路径映射
后端返回的 component 字段(如 home/index)会被映射到:
src/views/home/index.vue
要求:
- 确保组件文件存在
- 组件路径正确
🧪 测试验证
测试场景 1:正常登录
1. 启动项目
2. 访问登录页面
3. 输入用户名密码
4. 点击登录
5. 登录成功
6. 页面刷新
7. 进入系统首页 ✅
验证点:
- ✅ 首页正确显示
- ✅ 首页路由是
/home - ✅ 首页组件正确加载
测试场景 2:authorityMenus 接口失败
1. 启动项目
2. 登录(authorityMenus 接口失败)
3. 使用默认菜单配置
4. 页面刷新
5. 进入系统首页 ✅
验证点:
- ✅ 使用默认菜单配置
- ✅ 首页正确显示
- ✅ 控制台有警告信息
测试场景 3:刷新页面
1. 已登录状态
2. 刷新页面
3. 从 localStorage 读取菜单
4. 重新生成路由
5. 首页正确显示 ✅
验证点:
- ✅ 首页路由正确
- ✅ 菜单正确显示
- ✅ 用户状态保持
📝 总结
修改内容
- ✅ 移除了硬编码的首页路由
- ✅ 移除了
HomePage参数 - ✅ 简化了路由生成逻辑
- ✅ 统一了菜单处理方式
优势
- ✅ 代码更简洁(减少约 20 行代码)
- ✅ 逻辑更清晰
- ✅ 配置更灵活
- ✅ 维护更容易
要求
- ⚠️ 后端必须返回首页配置
- ⚠️ 首页路径必须是
/home - ⚠️ 组件文件必须存在
硬编码首页已移除! 🎉
现在首页完全由后端配置控制,代码更简洁、更灵活。