Files
sgxt_web/docs/navigation-issue-solution.md

130 lines
3.4 KiB
Markdown
Raw Normal View History

2026-04-28 11:26:26 +08:00
# 首页导航跳转问题分析与解决方案
## 问题现象
接口请求完成之前,首页的导航菜单无法跳转;接口请求完成后,导航跳转正常。
---
## 问题根源
### 核心问题SideBarMenu.vue 的页面刷新逻辑
```javascript
// 问题代码(已修复)
if (router.getRoutes().length <= 7 && store.state.permission.routeReady <= 1) {
setTimeout(() => {
router.go(0); // 触发页面刷新!
}, 200);
}
```
当动态路由还没添加完成时,这个条件会触发页面不断刷新,导致导航不可用。
---
## 已完成的修复
### 1. 修改 `src/store/modules/permission.js`
**修改内容**:优化 `routeReady` 状态管理0: 未开始 → 1: 进行中 → 2: 完成)
```javascript
actions: {
filterRoutes(context, menus) {
// 开始处理,标记为进行中
context.commit('setRouteReady', 1);
let routes = [];
if (menus && menus.length > 0) {
routes = filter(privateRoutes, menus);
}
routes.push({ path: '/:catchAll(.*)', redirect: '/404' });
context.commit('setRoutes', routes);
// 处理完成,标记为已完成
context.commit('setRouteReady', 2); // ← 新增:完成时设为 2
return routes;
}
}
```
### 2. 修改 `src/permission.js`
**修改内容**:移除了在路由守卫开始时设置 `setRouteReady(1)` 的代码,让 `filterRoutes` action 统一管理状态。
### 3. 修改 `src/layout/components/SideBar/SideBarMenu.vue`
**修改内容**:移除自动刷新页面的逻辑,改为监听路由加载状态
```javascript
// 原代码(已移除):
// if (router.getRoutes().length <= 7 && store.state.permission.routeReady <= 1) {
// store.commit("user/setIsReady", {});
// setTimeout(() => {
// router.go(0);
// }, 200);
// }
// 新代码:监听路由加载完成状态
if (store.state.permission.routeReady !== 2) {
const unwatch = watch(
() => store.state.permission.routeReady,
(val) => {
if (val === 2) {
unwatch();
}
},
{ immediate: true }
);
}
```
### 4. 修改 `src/utils/route.js`
**修改内容**:添加空值安全检查,避免 `deptId``roleList` 为空时报错
```javascript
// 原代码(可能报错):
// const { deptBizType, deptLevel } = getItem('deptId')[0]
// 新代码(安全):
const deptIdData = getItem('deptId');
const deptInfo = deptIdData && deptIdData.length > 0 ? deptIdData[0] : {};
const deptBizType = deptInfo.deptBizType || '';
const deptLevel = deptInfo.deptLevel || '';
const roleListData = getItem('roleList') || [];
const roleList = roleListData.filter(item => item.roleCode == 'JS_666666').length > 0;
const xjLsit = roleListData.filter(item => item.roleCode == 'JS_999999').length > 0;
```
---
## 修复后的流程
```
登录成功 → window.location.href = '/' → 页面加载
permission.js 路由守卫执行
filterRoutes 开始执行 → routeReady = 1进行中
动态路由添加完成 → routeReady = 2完成
SideBarMenu.vue 监听到 routeReady === 2
导航菜单正常渲染,可以跳转
```
---
## 修复文件列表
| 文件路径 | 修改内容 |
|---------|---------|
| `src/store/modules/permission.js` | 优化 routeReady 状态管理0→1→2 |
| `src/permission.js` | 移除重复的 setRouteReady 调用 |
| `src/layout/components/SideBar/SideBarMenu.vue` | 移除自动刷新逻辑,改为监听状态 |
| `src/utils/route.js` | 添加空值安全检查 |