docs: 添加项目详情页面导航菜单改造设计文档
This commit is contained in:
334
docs/plans/2026-03-04-project-detail-navigation-menu-design.md
Normal file
334
docs/plans/2026-03-04-project-detail-navigation-menu-design.md
Normal file
@@ -0,0 +1,334 @@
|
||||
# 项目详情页面导航菜单改造设计文档
|
||||
|
||||
## 概述
|
||||
|
||||
将项目详情页面(detail.vue)右侧的按钮组改为水平导航菜单,使用 Element UI Menu 组件实现简洁链接风格。
|
||||
|
||||
## 当前问题
|
||||
|
||||
项目详情页面右侧的操作按钮(上传数据、参数配置、初核结果)占用空间较大,视觉层级不够清晰,交互方式不够统一。
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 核心设计
|
||||
- 使用 Element UI 的 `el-menu` 组件(水平模式)
|
||||
- 菜单放在标题右侧,右对齐
|
||||
- "上传数据"和"参数配置"作为普通菜单项
|
||||
- "初核结果"保留下拉菜单结构,包含三个子项:结果总览、专项排查、流水明细查询
|
||||
- 采用简洁链接风格:透明背景 + 底部下划线激活效果
|
||||
|
||||
### 视觉风格
|
||||
- 默认状态:灰色文字(#606266),透明背景
|
||||
- Hover 状态:浅灰背景(#f5f7fa),深色文字(#303133)
|
||||
- 激活状态:蓝色文字(#1890ff)+ 底部 2px 蓝色下划线
|
||||
- 下拉菜单:白色背景,激活项浅蓝背景(#e6f7ff)
|
||||
|
||||
## 技术设计
|
||||
|
||||
### 1. 组件结构
|
||||
|
||||
#### detail.vue 模板改造
|
||||
|
||||
```vue
|
||||
<div class="header-right">
|
||||
<el-menu
|
||||
:default-active="activeTab"
|
||||
mode="horizontal"
|
||||
@select="handleMenuSelect"
|
||||
class="nav-menu"
|
||||
>
|
||||
<el-menu-item index="upload">上传数据</el-menu-item>
|
||||
<el-menu-item index="config">参数配置</el-menu-item>
|
||||
<el-submenu index="result">
|
||||
<template slot="title">初核结果</template>
|
||||
<el-menu-item index="overview">结果总览</el-menu-item>
|
||||
<el-menu-item index="special">专项排查</el-menu-item>
|
||||
<el-menu-item index="detail">流水明细查询</el-menu-item>
|
||||
</el-submenu>
|
||||
</el-menu>
|
||||
</div>
|
||||
|
||||
<!-- 动态组件渲染区域 -->
|
||||
<component
|
||||
:is="currentComponent"
|
||||
:project-id="projectId"
|
||||
:project-info="projectInfo"
|
||||
@menu-change="handleMenuChange"
|
||||
@data-uploaded="handleDataUploaded"
|
||||
@name-selected="handleNameSelected"
|
||||
@generate-report="handleGenerateReport"
|
||||
@fetch-bank-info="handleFetchBankInfo"
|
||||
/>
|
||||
```
|
||||
|
||||
### 2. 数据结构
|
||||
|
||||
```javascript
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'upload', // 当前激活的菜单项索引
|
||||
currentComponent: 'UploadData', // 当前显示的组件名称
|
||||
// ... 其他现有数据
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 交互逻辑
|
||||
|
||||
```javascript
|
||||
methods: {
|
||||
/** 菜单选择事件 */
|
||||
handleMenuSelect(index) {
|
||||
this.activeTab = index;
|
||||
|
||||
// 组件映射
|
||||
const componentMap = {
|
||||
'upload': 'UploadData',
|
||||
'config': 'ParamConfig',
|
||||
'overview': 'PreliminaryCheck',
|
||||
'special': 'SpecialCheck',
|
||||
'detail': 'DetailQuery'
|
||||
};
|
||||
|
||||
this.currentComponent = componentMap[index] || 'UploadData';
|
||||
},
|
||||
|
||||
// ... 其他现有方法
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 组件导入
|
||||
|
||||
```javascript
|
||||
import UploadData from "./components/detail/UploadData";
|
||||
import ParamConfig from "./components/detail/ParamConfig";
|
||||
import PreliminaryCheck from "./components/detail/PreliminaryCheck";
|
||||
import SpecialCheck from "./components/detail/SpecialCheck";
|
||||
import DetailQuery from "./components/detail/DetailQuery";
|
||||
|
||||
export default {
|
||||
name: "ProjectDetail",
|
||||
components: {
|
||||
UploadData,
|
||||
ParamConfig,
|
||||
PreliminaryCheck,
|
||||
SpecialCheck,
|
||||
DetailQuery,
|
||||
},
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## 样式设计
|
||||
|
||||
### 1. 导航菜单样式
|
||||
|
||||
```scss
|
||||
.header-right {
|
||||
.nav-menu {
|
||||
// 移除默认背景色和边框
|
||||
background-color: transparent;
|
||||
border-bottom: none;
|
||||
|
||||
// 菜单项基础样式
|
||||
.el-menu-item,
|
||||
.el-submenu__title {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
padding: 0 16px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
border-bottom: 2px solid transparent;
|
||||
|
||||
&:hover {
|
||||
background-color: #f5f7fa;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
// 激活状态:底部下划线 + 蓝色文字
|
||||
.el-menu-item.is-active {
|
||||
color: #1890ff;
|
||||
border-bottom: 2px solid #1890ff;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
// 下拉菜单激活状态
|
||||
.el-submenu.is-active > .el-submenu__title {
|
||||
color: #1890ff;
|
||||
border-bottom: 2px solid #1890ff;
|
||||
}
|
||||
|
||||
// 下拉菜单图标
|
||||
.el-submenu__icon-arrow {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 下拉菜单弹窗样式
|
||||
|
||||
```scss
|
||||
::v-deep .el-menu--popup {
|
||||
min-width: 140px;
|
||||
|
||||
.el-menu-item {
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
color: #1890ff;
|
||||
background-color: #e6f7ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 响应式适配
|
||||
|
||||
```scss
|
||||
@media (max-width: 768px) {
|
||||
.detail-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
||||
.header-right {
|
||||
width: 100%;
|
||||
margin-top: 12px;
|
||||
|
||||
.nav-menu {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
|
||||
.el-menu-item,
|
||||
.el-submenu {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 0 8px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 组件规范
|
||||
|
||||
### Props 接口
|
||||
|
||||
所有子组件应接收相同的 props:
|
||||
|
||||
```javascript
|
||||
props: {
|
||||
projectId: {
|
||||
type: [String, Number],
|
||||
default: null,
|
||||
},
|
||||
projectInfo: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
projectName: "",
|
||||
updateTime: "",
|
||||
projectStatus: "0",
|
||||
}),
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
### Events 接口
|
||||
|
||||
```javascript
|
||||
this.$emit('data-uploaded', { type: 'xxx' });
|
||||
this.$emit('generate-report');
|
||||
this.$emit('fetch-bank-info');
|
||||
this.$emit('menu-change', { key, route });
|
||||
this.$emit('name-selected', nameList);
|
||||
```
|
||||
|
||||
## 实施步骤
|
||||
|
||||
### 第一步:修改 detail.vue 文件
|
||||
1. 替换 header-right 中的按钮为 el-menu 组件
|
||||
2. 添加 activeTab 和 currentComponent 数据字段
|
||||
3. 实现 handleMenuSelect 方法
|
||||
4. 添加动态组件渲染区域
|
||||
5. 导入所有子组件
|
||||
|
||||
### 第二步:添加样式
|
||||
1. 添加导航菜单的自定义样式
|
||||
2. 添加下拉菜单样式
|
||||
3. 添加响应式样式
|
||||
|
||||
### 第三步:创建占位组件
|
||||
为未实现的功能创建占位组件:
|
||||
- ParamConfig.vue
|
||||
- PreliminaryCheck.vue
|
||||
- SpecialCheck.vue
|
||||
- DetailQuery.vue
|
||||
|
||||
### 第四步:测试验证
|
||||
- 功能测试:菜单切换、下拉菜单交互
|
||||
- 视觉测试:样式符合设计要求
|
||||
- 响应式测试:移动端布局正常
|
||||
|
||||
## 技术栈
|
||||
|
||||
- Element UI Menu 组件(`el-menu`, `el-menu-item`, `el-submenu`)
|
||||
- Vue 动态组件(`<component :is="...">`)
|
||||
- Scoped CSS 样式覆盖
|
||||
- Vue 2.6.12
|
||||
- Element UI 2.15.14
|
||||
|
||||
## 预期效果
|
||||
|
||||
### 视觉效果
|
||||
- 菜单项横向排列在标题右侧,右对齐
|
||||
- 简洁链接风格,无背景色和边框
|
||||
- 激活项显示蓝色文字和底部下划线
|
||||
- 下拉菜单样式统一
|
||||
|
||||
### 交互效果
|
||||
- 点击菜单项切换组件,URL 不变
|
||||
- 下拉菜单点击外部区域可关闭
|
||||
- 组件切换流畅,数据正确传递
|
||||
- 响应式布局在移动端自适应
|
||||
|
||||
## 代码改动量估算
|
||||
|
||||
- detail.vue 文件改动:约 80-100 行(模板 + 脚本 + 样式)
|
||||
- 占位组件创建:4 个文件,每个约 20 行
|
||||
- 总代码量:约 150-180 行
|
||||
|
||||
## 风险与注意事项
|
||||
|
||||
1. **组件文件不存在**:ParamConfig、PreliminaryCheck 等组件需要创建占位组件
|
||||
2. **样式覆盖**:Element UI 默认样式覆盖需要使用 `::v-deep` 或 `/deep/`
|
||||
3. **事件传递**:确保所有子组件的事件正确向上传递
|
||||
4. **路由监听**:移除原有路由相关的逻辑,改为组件状态管理
|
||||
|
||||
## 后续优化建议
|
||||
|
||||
1. 添加菜单切换动画效果
|
||||
2. 为占位组件实现完整功能
|
||||
3. 添加面包屑导航支持
|
||||
4. 支持菜单项权限控制
|
||||
5. 添加快捷键支持(Ctrl+Tab 切换)
|
||||
|
||||
## 测试清单
|
||||
|
||||
- [ ] 点击"上传数据"菜单,显示 UploadData 组件
|
||||
- [ ] 点击"参数配置"菜单,显示占位组件或 ParamConfig 组件
|
||||
- [ ] 点击"初核结果"菜单,展开下拉菜单
|
||||
- [ ] 点击下拉菜单子项,切换到对应组件
|
||||
- [ ] 激活菜单项显示底部下划线
|
||||
- [ ] Hover 菜单项显示浅灰背景
|
||||
- [ ] 下拉菜单点击外部区域关闭
|
||||
- [ ] 组件切换时 projectId 和 projectInfo 正确传递
|
||||
- [ ] 移动端菜单响应式布局正常
|
||||
- [ ] 现有功能不受影响(返回按钮、项目信息显示等)
|
||||
Reference in New Issue
Block a user