344 lines
14 KiB
Markdown
344 lines
14 KiB
Markdown
# 业务组件
|
||
|
||
<cite>
|
||
**本文引用的文件列表**
|
||
- [SidebarLogo.vue](file://frontend/src/components/SidebarLogo.vue)
|
||
- [TabsView.vue](file://frontend/src/components/TabsView.vue)
|
||
- [ChangePasswordDialog.vue](file://frontend/src/components/ChangePasswordDialog.vue)
|
||
- [index.vue](file://frontend/src/layout/index.vue)
|
||
- [tabs.js](file://frontend/src/utils/tabs.js)
|
||
- [auth.js](file://frontend/src/utils/auth.js)
|
||
- [index.js](file://frontend/src/router/index.js)
|
||
- [lux-theme.css](file://frontend/src/styles/lux-theme.css)
|
||
- [auth.js](file://frontend/src/api/auth.js)
|
||
- [index.vue](file://frontend/src/views/home/index.vue)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [简介](#简介)
|
||
2. [项目结构](#项目结构)
|
||
3. [核心组件](#核心组件)
|
||
4. [架构总览](#架构总览)
|
||
5. [组件详解](#组件详解)
|
||
6. [依赖关系分析](#依赖关系分析)
|
||
7. [性能考量](#性能考量)
|
||
8. [故障排查指南](#故障排查指南)
|
||
9. [结论](#结论)
|
||
10. [附录](#附录)
|
||
|
||
## 简介
|
||
本文件为业务组件的综合技术文档,聚焦于以下三个通用业务组件:
|
||
- 侧边栏Logo组件:负责品牌展示与侧边栏折叠态下的视觉呈现。
|
||
- 标签页视图组件:提供页面级标签页导航、上下文菜单、持久化与缓存策略。
|
||
- 密码修改对话框:提供安全的密码变更流程,含表单校验与后端交互。
|
||
|
||
文档将从设计理念、实现细节、接口定义、事件与插槽、样式定制、使用示例与最佳实践、组件协作与状态管理、可访问性与性能优化等方面进行系统阐述,并辅以可视化图表帮助理解。
|
||
|
||
## 项目结构
|
||
该前端工程采用 Vue 3 + Element Plus 架构,组件位于 frontend/src/components,布局与路由位于 layout 与 router 目录,主题样式集中于 styles,工具函数与 API 封装分别在 utils 与 api。
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "布局层"
|
||
L["layout/index.vue"]
|
||
end
|
||
subgraph "组件层"
|
||
SL["components/SidebarLogo.vue"]
|
||
TV["components/TabsView.vue"]
|
||
CPD["components/ChangePasswordDialog.vue"]
|
||
end
|
||
subgraph "工具与配置"
|
||
RT["router/index.js"]
|
||
TABS["utils/tabs.js"]
|
||
AUTH["utils/auth.js"]
|
||
THEME["styles/lux-theme.css"]
|
||
end
|
||
subgraph "视图层"
|
||
HOME["views/home/index.vue"]
|
||
end
|
||
subgraph "API"
|
||
API_AUTH["api/auth.js"]
|
||
end
|
||
L --> SL
|
||
L --> TV
|
||
L --> CPD
|
||
L --> RT
|
||
TV --> TABS
|
||
L --> AUTH
|
||
L --> THEME
|
||
CPD --> API_AUTH
|
||
RT --> HOME
|
||
```
|
||
|
||
图表来源
|
||
- [index.vue:1-338](file://frontend/src/layout/index.vue#L1-L338)
|
||
- [SidebarLogo.vue:1-135](file://frontend/src/components/SidebarLogo.vue#L1-L135)
|
||
- [TabsView.vue:1-351](file://frontend/src/components/TabsView.vue#L1-L351)
|
||
- [ChangePasswordDialog.vue:1-128](file://frontend/src/components/ChangePasswordDialog.vue#L1-L128)
|
||
- [index.js:1-91](file://frontend/src/router/index.js#L1-L91)
|
||
- [tabs.js:1-9](file://frontend/src/utils/tabs.js#L1-L9)
|
||
- [auth.js:1-99](file://frontend/src/utils/auth.js#L1-L99)
|
||
- [lux-theme.css:1-471](file://frontend/src/styles/lux-theme.css#L1-L471)
|
||
- [auth.js:1-24](file://frontend/src/api/auth.js#L1-L24)
|
||
- [index.vue:1-327](file://frontend/src/views/home/index.vue#L1-L327)
|
||
|
||
章节来源
|
||
- [index.vue:1-338](file://frontend/src/layout/index.vue#L1-L338)
|
||
- [index.js:1-91](file://frontend/src/router/index.js#L1-L91)
|
||
|
||
## 核心组件
|
||
- 侧边栏Logo组件:通过 props 控制折叠态,渲染品牌标识与品牌名/标签,支持折叠时隐藏文字,保持视觉简洁。
|
||
- 标签页视图组件:基于 Element Plus Tabs 实现,自动根据路由生成标签、支持右键上下文菜单、持久化到 sessionStorage、结合 KeepAlive 缓存页面。
|
||
- 密码修改对话框:基于 Element Plus Dialog/Form,内置表单规则与加载态,调用后端接口完成密码变更。
|
||
|
||
章节来源
|
||
- [SidebarLogo.vue:52-59](file://frontend/src/components/SidebarLogo.vue#L52-L59)
|
||
- [TabsView.vue:55-287](file://frontend/src/components/TabsView.vue#L55-L287)
|
||
- [ChangePasswordDialog.vue:51-127](file://frontend/src/components/ChangePasswordDialog.vue#L51-L127)
|
||
|
||
## 架构总览
|
||
组件间协作关系如下:
|
||
- 布局容器负责组织侧边栏、头部、主内容区与底部;在头部触发“修改密码”动作,打开密码修改对话框。
|
||
- 标签页视图组件监听路由变化,动态增删标签并持久化;通过 KeepAlive 缓存页面,提升切换体验。
|
||
- 侧边栏Logo组件接收折叠状态,影响品牌展示形态。
|
||
- 密码修改对话框通过 API 层发起请求,成功后提示并关闭对话框。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant U as "用户"
|
||
participant L as "布局容器"
|
||
participant H as "头部下拉菜单"
|
||
participant D as "密码修改对话框"
|
||
participant API as "认证API"
|
||
participant S as "会话存储"
|
||
U->>H : 点击“修改密码”
|
||
H->>L : 触发命令
|
||
L->>D : 打开对话框(v-model)
|
||
U->>D : 输入旧/新/确认密码
|
||
D->>D : 表单校验
|
||
D->>API : 提交修改密码
|
||
API-->>D : 返回结果
|
||
D-->>U : 成功消息
|
||
D->>L : 关闭对话框(v-model)
|
||
L->>S : 可选:清理相关状态
|
||
```
|
||
|
||
图表来源
|
||
- [index.vue:95-141](file://frontend/src/layout/index.vue#L95-L141)
|
||
- [ChangePasswordDialog.vue:1-128](file://frontend/src/components/ChangePasswordDialog.vue#L1-L128)
|
||
- [auth.js:14-23](file://frontend/src/api/auth.js#L14-L23)
|
||
|
||
## 组件详解
|
||
|
||
### 侧边栏Logo组件(SidebarLogo)
|
||
- 设计理念
|
||
- 在折叠态下仅保留品牌标识,非折叠态显示品牌名与标签,保证信息密度与可读性的平衡。
|
||
- 使用 SVG 渐变与阴影增强品牌识别度,配合主题变量实现深色风格适配。
|
||
- Props 接口
|
||
- collapsed: Boolean,默认 false,控制是否处于折叠态。
|
||
- 插槽与事件
|
||
- 无插槽;无自定义事件。
|
||
- 样式定制
|
||
- 支持通过主题变量与容器类名调整尺寸、间距与颜色。
|
||
- 使用示例
|
||
- 在布局侧栏中直接使用,传入 isSidebarCollapsed 的响应式布尔值。
|
||
- 最佳实践
|
||
- 折叠态时隐藏文字,避免溢出;保持 SVG 图标尺寸与容器一致。
|
||
- 可访问性
|
||
- 品牌标识区域设置 aria-hidden;标题通过外部语义元素提供。
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class SidebarLogo {
|
||
+Boolean collapsed
|
||
}
|
||
```
|
||
|
||
图表来源
|
||
- [SidebarLogo.vue:52-59](file://frontend/src/components/SidebarLogo.vue#L52-L59)
|
||
|
||
章节来源
|
||
- [SidebarLogo.vue:1-135](file://frontend/src/components/SidebarLogo.vue#L1-L135)
|
||
- [lux-theme.css:100-148](file://frontend/src/styles/lux-theme.css#L100-L148)
|
||
|
||
### 标签页视图组件(TabsView)
|
||
- 设计理念
|
||
- 自动同步路由生成标签,支持点击切换、右键上下文菜单(关闭、关闭其他、关闭全部)、持久化与缓存。
|
||
- 通过 KeepAlive 缓存页面实例,减少重复渲染与网络请求。
|
||
- Props 接口
|
||
- 无显式 props。
|
||
- 事件与插槽
|
||
- 无自定义事件;使用默认插槽渲染标签标题。
|
||
- 数据模型与逻辑
|
||
- 内部维护 tabs 数组与 activeKey,normalizeTabFromRoute 从路由元信息生成标签项。
|
||
- 持久化键值:TABS_STORAGE_KEY;默认首页路径:HOME_PATH。
|
||
- 上下文菜单命令处理:关闭、关闭其他、关闭全部。
|
||
- 性能特性
|
||
- 使用 computed 计算 keepAliveInclude,避免重复缓存同名组件。
|
||
- watch 监听路由与 tabs/activeKey 变化,按需持久化。
|
||
- 使用示例
|
||
- 在布局主内容区直接引入 TabsView,即可获得完整的多标签页导航体验。
|
||
- 最佳实践
|
||
- 路由 meta.title 与 meta.icon 用于标签标题与图标;避免将根布局路由加入标签。
|
||
- 可访问性
|
||
- 标签项具备可点击与可关闭语义;上下文菜单提供键盘可达性。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start(["挂载"]) --> Restore["恢复标签与激活项"]
|
||
Restore --> Upsert["根据当前路由更新标签"]
|
||
Upsert --> WatchRoute["监听路由变化"]
|
||
WatchRoute --> Persist["持久化标签状态"]
|
||
Persist --> End(["运行中"])
|
||
```
|
||
|
||
图表来源
|
||
- [TabsView.vue:270-286](file://frontend/src/components/TabsView.vue#L270-L286)
|
||
- [tabs.js:1-9](file://frontend/src/utils/tabs.js#L1-L9)
|
||
|
||
章节来源
|
||
- [TabsView.vue:1-351](file://frontend/src/components/TabsView.vue#L1-L351)
|
||
- [tabs.js:1-9](file://frontend/src/utils/tabs.js#L1-L9)
|
||
|
||
### 密码修改对话框(ChangePasswordDialog)
|
||
- 设计理念
|
||
- 安全优先:表单字段类型为 password,开启 show-password;提交前严格校验;加载态防止重复提交。
|
||
- 用户友好:错误提示明确,成功后自动关闭并提示。
|
||
- Props 接口
|
||
- modelValue: Boolean,默认 false,双向绑定控制对话框显示/隐藏。
|
||
- 事件
|
||
- update:modelValue:用于父组件同步 visible 状态。
|
||
- 插槽
|
||
- 无插槽。
|
||
- 样式定制
|
||
- 基于 Element Plus 对话框样式,可借助主题变量统一风格。
|
||
- 使用示例
|
||
- 在布局头部下拉菜单中触发,通过 v-model 控制显示。
|
||
- 最佳实践
|
||
- 提交前先 validate;捕获异常并重置 loading;成功后清空表单。
|
||
- 可访问性
|
||
- 表单项具备 label 与占位提示;按钮具备可读性文本。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant U as "用户"
|
||
participant L as "布局容器"
|
||
participant D as "密码修改对话框"
|
||
participant F as "表单校验"
|
||
participant API as "认证API"
|
||
U->>L : 点击“修改密码”
|
||
L->>D : v-model=true
|
||
U->>D : 输入旧/新/确认密码
|
||
D->>F : validate()
|
||
F-->>D : 校验通过
|
||
D->>API : changePassword(old,new)
|
||
API-->>D : 返回结果
|
||
D-->>U : 显示成功消息
|
||
D->>L : v-model=false
|
||
```
|
||
|
||
图表来源
|
||
- [index.vue:118-123](file://frontend/src/layout/index.vue#L118-L123)
|
||
- [ChangePasswordDialog.vue:51-127](file://frontend/src/components/ChangePasswordDialog.vue#L51-L127)
|
||
- [auth.js:14-23](file://frontend/src/api/auth.js#L14-L23)
|
||
|
||
章节来源
|
||
- [ChangePasswordDialog.vue:1-128](file://frontend/src/components/ChangePasswordDialog.vue#L1-L128)
|
||
- [auth.js:14-23](file://frontend/src/api/auth.js#L14-L23)
|
||
|
||
## 依赖关系分析
|
||
- 组件耦合
|
||
- TabsView 依赖路由与工具常量(TABS_STORAGE_KEY、HOME_PATH),并与 KeepAlive 协作实现缓存。
|
||
- Layout 同时依赖 TabsView、SidebarLogo、ChangePasswordDialog,形成页面骨架与交互闭环。
|
||
- ChangePasswordDialog 依赖 API 层与 Element Plus 组件。
|
||
- 外部依赖
|
||
- Vue 3、Vue Router、Element Plus、@element-plus/icons-vue。
|
||
- 潜在循环依赖
|
||
- 未发现组件间循环依赖;布局与组件分层清晰。
|
||
|
||
```mermaid
|
||
graph LR
|
||
TV["TabsView.vue"] --> RT["router/index.js"]
|
||
TV --> TABS["utils/tabs.js"]
|
||
L["layout/index.vue"] --> TV
|
||
L --> SL["SidebarLogo.vue"]
|
||
L --> CPD["ChangePasswordDialog.vue"]
|
||
CPD --> API["api/auth.js"]
|
||
L --> AUTH["utils/auth.js"]
|
||
L --> THEME["styles/lux-theme.css"]
|
||
```
|
||
|
||
图表来源
|
||
- [TabsView.vue:55-59](file://frontend/src/components/TabsView.vue#L55-L59)
|
||
- [index.js:1-91](file://frontend/src/router/index.js#L1-L91)
|
||
- [tabs.js:1-9](file://frontend/src/utils/tabs.js#L1-L9)
|
||
- [index.vue:1-338](file://frontend/src/layout/index.vue#L1-L338)
|
||
- [SidebarLogo.vue:1-135](file://frontend/src/components/SidebarLogo.vue#L1-L135)
|
||
- [ChangePasswordDialog.vue:1-128](file://frontend/src/components/ChangePasswordDialog.vue#L1-L128)
|
||
- [auth.js:1-24](file://frontend/src/api/auth.js#L1-L24)
|
||
- [auth.js:1-99](file://frontend/src/utils/auth.js#L1-L99)
|
||
- [lux-theme.css:1-471](file://frontend/src/styles/lux-theme.css#L1-L471)
|
||
|
||
章节来源
|
||
- [index.js:1-91](file://frontend/src/router/index.js#L1-L91)
|
||
- [lux-theme.css:1-471](file://frontend/src/styles/lux-theme.css#L1-L471)
|
||
|
||
## 性能考量
|
||
- 标签页缓存
|
||
- 使用 KeepAlive 结合 computed 的 include 列表,避免重复渲染与网络请求。
|
||
- 路由监听与持久化
|
||
- 仅在 tabs/activeKey 发生变化时写入 sessionStorage,降低 IO 开销。
|
||
- 折叠态 Logo
|
||
- 折叠时隐藏文字,减少 DOM 与重排成本。
|
||
- 对话框加载态
|
||
- 提交期间禁用按钮并显示 loading,避免重复提交与资源浪费。
|
||
- 主题与样式
|
||
- 使用 CSS 变量统一颜色与阴影,减少重复样式计算。
|
||
|
||
## 故障排查指南
|
||
- 标签页不显示或丢失
|
||
- 检查路由 meta.title/meta.icon 是否正确设置;确认 HOME_PATH 常量与默认首页一致。
|
||
- 查看 sessionStorage 中的 TABS_STORAGE_KEY 是否被清理或损坏。
|
||
- 密码修改失败
|
||
- 确认旧密码正确且新密码满足长度要求;检查 API 返回码与网络状态。
|
||
- 若出现重复提交,确认 loading 状态与 validate 流程。
|
||
- 侧边栏折叠异常
|
||
- 检查 isSidebarCollapsed 的绑定与鼠标事件;确认主题样式未被覆盖。
|
||
|
||
章节来源
|
||
- [TabsView.vue:125-174](file://frontend/src/components/TabsView.vue#L125-L174)
|
||
- [ChangePasswordDialog.vue:108-126](file://frontend/src/components/ChangePasswordDialog.vue#L108-L126)
|
||
- [index.vue:10-15](file://frontend/src/layout/index.vue#L10-L15)
|
||
|
||
## 结论
|
||
本项目通过三个核心业务组件构建了清晰、可扩展的前端界面骨架:侧边栏Logo承担品牌展示职责,标签页视图提供高效导航与缓存,密码修改对话框保障安全交互。组件间通过布局容器与路由系统协同工作,配合主题样式与工具函数,实现了良好的可维护性与用户体验。
|
||
|
||
## 附录
|
||
|
||
### 组件接口速查
|
||
|
||
- 侧边栏Logo组件
|
||
- Props: collapsed(Boolean)
|
||
- 事件: 无
|
||
- 插槽: 无
|
||
- 样式: 通过主题变量与容器类名定制
|
||
|
||
- 标签页视图组件
|
||
- Props: 无
|
||
- 事件: 无
|
||
- 插槽: 默认插槽(label)
|
||
- 数据: tabs(Array), activeKey(String), keepAliveInclude(Set)
|
||
- 常量: TABS_STORAGE_KEY(String), HOME_PATH(String)
|
||
|
||
- 密码修改对话框
|
||
- Props: modelValue(Boolean)
|
||
- 事件: update:modelValue(Boolean)
|
||
- 插槽: 无
|
||
- 表单: oldPassword, newPassword, confirmPassword
|
||
- 校验: 必填、最小长度、确认一致性
|
||
|
||
章节来源
|
||
- [SidebarLogo.vue:52-59](file://frontend/src/components/SidebarLogo.vue#L52-L59)
|
||
- [TabsView.vue:55-287](file://frontend/src/components/TabsView.vue#L55-L287)
|
||
- [ChangePasswordDialog.vue:51-127](file://frontend/src/components/ChangePasswordDialog.vue#L51-L127)
|
||
- [tabs.js:1-9](file://frontend/src/utils/tabs.js#L1-L9) |