233 lines
6.2 KiB
Markdown
233 lines
6.2 KiB
Markdown
# system-info 页面侧边栏问题完整解决方案
|
||
|
||
## 问题描述
|
||
|
||
用户反映 `pages/mall/admin/maintain/system-info.uvue` 页面:
|
||
|
||
1. 没有侧边栏显示
|
||
2. 菜单高亮跳转到首页
|
||
|
||
## 根本原因分析
|
||
|
||
### 1. system-info 在菜单中的特殊结构
|
||
|
||
在 `layouts/admin/utils/menu.uts` 中,`system-info` 是作为 **MenuGroup 叶子节点** 存在:
|
||
|
||
```ts
|
||
{
|
||
id: 'system-info',
|
||
title: '系统信息',
|
||
path: '/pages/mall/admin/maintain/system-info',
|
||
children: [] // 叶子节点:有 id/title/path,但 children 为空数组
|
||
}
|
||
```
|
||
|
||
### 2. 匹配逻辑修复记录
|
||
|
||
在 `layouts/admin/utils/nav.uts` 的 `findActiveByCurrentPage` 函数中,已经添加了对 group 叶子节点的支持:
|
||
|
||
```ts
|
||
for (const g of groups) {
|
||
// ✅ group 叶子(可选)- 检查 id
|
||
if (g.id === page) {
|
||
return { activeMenuId: m.id, activeSubId: g.id };
|
||
}
|
||
// ✅ group 叶子(可选)- 检查 path
|
||
if (g.path && normalize(g.path) === pageNorm) {
|
||
return { activeMenuId: m.id, activeSubId: g.id };
|
||
}
|
||
// ... 继续检查 children
|
||
}
|
||
```
|
||
|
||
### 3. 生命周期修复
|
||
|
||
在 `layouts/admin/AdminLayout.uvue` 中已正确配置:
|
||
|
||
```ts
|
||
import { onShow } from "@dcloudio/uni-app";
|
||
|
||
// 监听 currentPage 变化(immediate: true 确保首次渲染时同步)
|
||
watch(
|
||
() => props.currentPage,
|
||
() => syncActiveByCurrentPage(),
|
||
{ immediate: true },
|
||
);
|
||
|
||
// 页面显示时同步(包括从其他页面返回)
|
||
onMounted(() => syncActiveByCurrentPage());
|
||
onShow(() => syncActiveByCurrentPage());
|
||
```
|
||
|
||
### 4. 面包屑支持 group 叶子节点
|
||
|
||
修复了 breadcrumb computed 属性:
|
||
|
||
```ts
|
||
const breadcrumb = computed(() => {
|
||
let subTitle = "";
|
||
const groups = activeGroups.value;
|
||
for (const g of groups) {
|
||
// ✅ 检查 group 本身是否是当前激活项(叶子节点)
|
||
if (g.id === activeSubId.value) {
|
||
subTitle = g.title;
|
||
break;
|
||
}
|
||
// 检查 group 的 children
|
||
const cs = g.children ?? [];
|
||
const hit = cs.find((c) => c.id === activeSubId.value);
|
||
if (hit) {
|
||
subTitle = hit.title;
|
||
break;
|
||
}
|
||
}
|
||
return subTitle
|
||
? `${activeMenuTitle.value} / ${subTitle}`
|
||
: `${activeMenuTitle.value}`;
|
||
});
|
||
```
|
||
|
||
## 验证测试
|
||
|
||
### 测试脚本验证(test-nav.js)
|
||
|
||
```
|
||
输入: "system-info"
|
||
结果: activeMenuId="maintain", activeSubId="system-info"
|
||
说明: 命中 group.id ✅
|
||
|
||
输入: "/pages/mall/admin/maintain/system-info"
|
||
结果: activeMenuId="maintain", activeSubId="system-info"
|
||
说明: 命中 group.path ✅
|
||
|
||
输入: "pages/mall/admin/maintain/system-info"
|
||
结果: activeMenuId="maintain", activeSubId="system-info"
|
||
说明: 命中 group.path ✅
|
||
```
|
||
|
||
## 完整修复清单
|
||
|
||
### 已完成的修复
|
||
|
||
✅ **nav.uts**: findActiveByCurrentPage 支持 group.id 和 group.path 匹配
|
||
✅ **AdminLayout.uvue**:
|
||
|
||
- 正确导入 onShow from '@dcloudio/uni-app'
|
||
- watch immediate: true
|
||
- onMounted + onShow 生命周期
|
||
✅ **AdminLayout.uvue**: breadcrumb 支持 group 叶子节点
|
||
✅ **AdminSubSider.uvue**: 完整支持 group 叶子节点(groupAsChild、handleGroupTitleClick)
|
||
✅ **state.uts**: 跨页面单例状态(isCollapsed, tabs, activeTabId, hasNotification)
|
||
✅ **system-info.uvue**: 规范化 SFC 结构,移除多余空行和字符
|
||
|
||
### SFC 结构修复
|
||
|
||
修复了以下文件的 SFC 结构(移除 `</style>` 后的多余内容):
|
||
|
||
- pages/mall/admin/maintain/system-info.uvue
|
||
- pages/mall/admin/maintain/data/clear-data.uvue
|
||
- pages/mall/admin/maintain/data/logistics-company.uvue
|
||
- pages/mall/admin/maintain/dev-config/combination-data.uvue
|
||
- pages/mall/admin/maintain/dev-config/cron-job.uvue
|
||
- pages/mall/admin/maintain/dev-config/module-config.uvue
|
||
|
||
## 预期效果
|
||
|
||
### 进入 system-info 页面时
|
||
|
||
1. **主侧边栏(AdminAside)**: 始终显示,"维护" 菜单高亮
|
||
2. **二级侧边栏(AdminSubSider)**: 显示维护模块的所有分组,"系统信息" 项高亮
|
||
3. **面包屑**: 显示 "维护 / 系统信息"
|
||
4. **activeMenuId**: "maintain"
|
||
5. **activeSubId**: "system-info"
|
||
6. **activeGroups**: maintain 菜单的 groups 数组(包含多个分组)
|
||
|
||
### 关键状态流转
|
||
|
||
```
|
||
页面渲染
|
||
↓
|
||
AdminLayout setup 执行
|
||
↓
|
||
syncActiveByCurrentPage() [watch immediate 触发]
|
||
↓
|
||
findActiveByCurrentPage(menuList, 'system-info')
|
||
↓
|
||
命中 group.id === 'system-info'
|
||
↓
|
||
返回 { activeMenuId: 'maintain', activeSubId: 'system-info' }
|
||
↓
|
||
activeGroups = maintain.groups (非空数组)
|
||
↓
|
||
v-if="activeGroups.length > 0" → AdminSubSider 渲染
|
||
↓
|
||
AdminSubSider 内部 resolvedActiveId = 'system-info'
|
||
↓
|
||
系统信息项显示高亮样式
|
||
```
|
||
|
||
## 如何验证
|
||
|
||
### 方法1: 开发服务器(需要项目支持)
|
||
|
||
```bash
|
||
cd d:\骅锋\mall
|
||
# 添加 dev:h5 脚本到 package.json,或使用 HBuilderX 运行
|
||
```
|
||
|
||
### 方法2: ESLint 验证(已通过)
|
||
|
||
```bash
|
||
npm run lint
|
||
# 确认无 vue/no-parsing-error 或 vue/html-end-tags 错误
|
||
```
|
||
|
||
### 方法3: 代码逻辑验证(已完成)
|
||
|
||
- ✅ test-nav.js 测试通过
|
||
- ✅ 所有关键函数逻辑审查通过
|
||
- ✅ SFC 结构验证通过
|
||
|
||
## 故障排查
|
||
|
||
如果问题仍然存在,请检查:
|
||
|
||
1. **@ 别名是否配置正确**
|
||
- 如果 `@/layouts/admin/AdminLayout.uvue` 无法解析
|
||
- 改用相对路径: `../../../layouts/admin/AdminLayout.uvue`
|
||
|
||
2. **确认 menu.uts 中 system-info 配置**
|
||
|
||
```bash
|
||
grep -n "system-info" d:\骅锋\mall\layouts\admin\utils\menu.uts
|
||
```
|
||
|
||
3. **检查控制台是否有 Vue 警告**
|
||
- 打开浏览器开发者工具
|
||
- 查看 Console 面板
|
||
- 搜索 "AdminLayout" 或 "system-info"
|
||
|
||
4. **验证 state.uts 是否被正确导入**
|
||
```ts
|
||
// 在 AdminLayout.uvue 中
|
||
import {
|
||
tabs,
|
||
activeTabId,
|
||
isCollapsed,
|
||
hasNotification,
|
||
} from "./state.uts";
|
||
```
|
||
|
||
## 总结
|
||
|
||
问题已从以下几个层面完全解决:
|
||
|
||
1. **数据层**: menu.uts 结构正确(system-info 作为 group 叶子)
|
||
2. **逻辑层**: nav.uts 匹配函数支持所有节点类型
|
||
3. **组件层**: AdminLayout 和 AdminSubSider 完整支持
|
||
4. **生命周期层**: watch + onMounted + onShow 确保状态同步
|
||
5. **状态层**: state.uts 单例模式防止状态重置
|
||
6. **结构层**: SFC 规范化,无多余字符干扰解析
|
||
|
||
如需进一步调试,请提供浏览器控制台的错误信息或截图。
|