# 组件设计模式
**本文引用的文件**
- [frontend/src/App.vue](file://frontend/src/App.vue)
- [frontend/src/main.js](file://frontend/src/main.js)
- [frontend/src/router/index.js](file://frontend/src/router/index.js)
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue)
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue)
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue)
- [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue)
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue)
- [frontend/src/views/assessment/AssessmentDetail.vue](file://frontend/src/views/assessment/AssessmentDetail.vue)
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js)
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js)
- [frontend/src/stores/index.js](file://frontend/src/stores/index.js)
- [frontend/src/api/index.js](file://frontend/src/api/index.js)
- [frontend/vite.config.js](file://frontend/vite.config.js)
- [frontend/package.json](file://frontend/package.json)
## 目录
1. [引言](#引言)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [组件详解](#组件详解)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 引言
本指南围绕 Vue 组件设计模式,结合仓库中的前端实现,系统阐述组件拆分原则、单一职责与高内聚低耦合理念;容器组件与展示组件的分离;组件抽象与复用策略;组件通信(父子、兄弟、跨级、事件总线);状态管理(全局与局部);组件边界与接口设计;以及测试策略与 Mock 数据实践。目标是帮助读者在实际项目中构建清晰、可维护、可扩展的组件体系。
## 项目结构
前端采用典型的单页应用结构:入口应用、路由、布局、业务视图、状态管理与 API 层。整体遵循“关注点分离”和“按功能域组织”的原则,便于团队协作与长期演进。
```mermaid
graph TB
A["main.js
应用入口"] --> B["App.vue
根组件"]
A --> C["router/index.js
路由配置"]
A --> D["stores/*
Pinia 状态"]
A --> E["api/*
API 导出聚合"]
B --> F["router-view
动态渲染视图"]
F --> G["Layout.vue
布局容器"]
G --> H["views/*
业务视图"]
subgraph "业务视图"
H1["Login.vue"]
H2["Dashboard.vue"]
H3["basic/Departments.vue"]
H4["assessment/Assessments.vue"]
H5["assessment/AssessmentDetail.vue"]
end
G --> H1
G --> H2
G --> H3
G --> H4
G --> H5
```
图表来源
- [frontend/src/main.js](file://frontend/src/main.js#L1-L24)
- [frontend/src/App.vue](file://frontend/src/App.vue#L1-L17)
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L1-L116)
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
章节来源
- [frontend/src/main.js](file://frontend/src/main.js#L1-L24)
- [frontend/src/App.vue](file://frontend/src/App.vue#L1-L17)
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L1-L116)
## 核心组件
- 应用入口与根组件
- 入口负责注册插件、挂载应用;根组件提供语言环境与路由出口。
- 路由层
- 定义页面级路由、嵌套路由与导航守卫,统一设置标题与鉴权跳转。
- 布局容器
- 提供侧边栏、面包屑、头部用户信息与主内容区,承载业务视图切换与动画。
- 业务视图
- 各功能域页面(如登录、仪表盘、基础数据、考核管理等),承担数据加载、交互与展示。
- 状态管理
- Pinia Store 提供用户态与应用态(如侧边栏折叠、科室树)管理。
- API 聚合
- 统一导出各模块 API 方法,便于视图组件按需引入。
章节来源
- [frontend/src/App.vue](file://frontend/src/App.vue#L1-L17)
- [frontend/src/main.js](file://frontend/src/main.js#L1-L24)
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L1-L116)
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
- [frontend/src/api/index.js](file://frontend/src/api/index.js#L1-L9)
## 架构总览
系统采用“布局容器 + 页面视图 + 状态管理 + API 调用”的分层架构。路由驱动视图切换,Pinia 管理共享状态,Element Plus 提供 UI 基础能力,Vite 提供开发与代理能力。
```mermaid
graph TB
subgraph "运行时"
R["浏览器"]
V["Vue 3 运行时"]
P["Pinia 状态"]
E["Element Plus UI"]
AX["Axios 请求"]
end
R --> V
V --> E
V --> P
V --> AX
AX --> S["后端服务
http://localhost:8000"]
```
图表来源
- [frontend/src/main.js](file://frontend/src/main.js#L1-L24)
- [frontend/vite.config.js](file://frontend/vite.config.js#L1-L22)
- [frontend/package.json](file://frontend/package.json#L1-L27)
## 组件详解
### 布局容器组件(Layout)
- 角色定位
- 容器组件:负责页面骨架、菜单渲染、侧边栏折叠、面包屑与用户下拉。
- 设计要点
- 通过 Pinia 管理侧边栏折叠状态;从 API 加载菜单树并映射为前端菜单项。
- 使用路由元信息设置页面标题;在登出时清理状态并跳转登录。
- 边界与接口
- 依赖:路由实例、用户与应用 Store、菜单 API。
- 输出:菜单项数组、折叠状态、路由元信息标题。
- 复用策略
- 将菜单加载逻辑抽离为可复用的工具函数;对菜单树转换逻辑进行单元测试。
```mermaid
sequenceDiagram
participant U as "用户"
participant L as "Layout.vue"
participant S as "Store(user/app)"
participant A as "API(menu)"
participant R as "Router"
U->>L : 打开页面
L->>S : 读取折叠状态/用户信息
L->>A : 加载菜单树
A-->>L : 返回菜单数据
L->>L : 转换为前端菜单项
L->>R : 设置页面标题
U->>L : 点击菜单/折叠按钮
L->>S : 更新折叠状态
L->>R : 导航到目标路由
```
图表来源
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L73-L125)
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L104-L113)
章节来源
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L104-L113)
### 登录组件(Login)
- 角色定位
- 展示组件:负责表单输入、校验与登录交互。
- 设计要点
- 表单校验规则;调用用户 Store 的登录方法;成功后提示与路由跳转;失败提示。
- 边界与接口
- 输入:表单数据(用户名/密码);输出:登录结果与路由跳转。
- 复用策略
- 将表单校验规则与消息提示封装为可复用的组合式函数;对登录流程进行单元测试。
```mermaid
sequenceDiagram
participant U as "用户"
participant L as "Login.vue"
participant S as "Store(user)"
participant R as "Router"
U->>L : 输入用户名/密码
U->>L : 点击登录
L->>L : 校验表单
alt 校验通过
L->>S : 调用 login(username,password)
S-->>L : 返回布尔结果
alt 成功
L->>U : 显示成功消息
L->>R : 跳转 /
else 失败
L->>U : 显示失败消息
end
else 校验失败
L->>U : 显示校验提示
end
```
图表来源
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L73-L89)
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L11-L20)
章节来源
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
### 仪表盘组件(Dashboard)
- 角色定位
- 容器组件:负责多维度数据加载、图表初始化与渲染、告警提示与表格展示。
- 设计要点
- 多个图表(趋势、饼图、科室排名、仪表盘)的初始化与响应式适配;计算属性用于派生指标;异常数据兜底。
- 边界与接口
- 输入:周期参数;输出:统计卡片、图表数据、告警集合。
- 复用策略
- 将图表配置与更新函数抽取为可复用的工具;对数据格式化与图表选项生成进行单元测试。
```mermaid
flowchart TD
Start(["进入 Dashboard"]) --> LoadStats["加载统计数据"]
LoadStats --> LoadRanking["加载员工排名"]
LoadRanking --> LoadTrend["加载趋势数据"]
LoadTrend --> LoadDeptRanking["加载科室排名"]
LoadDeptRanking --> LoadFinance["加载财务趋势"]
LoadFinance --> LoadKpi["加载关键指标仪表盘"]
LoadKpi --> InitCharts["初始化图表实例"]
InitCharts --> RenderCharts["渲染图表与告警"]
RenderCharts --> End(["完成渲染"])
```
图表来源
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L329-L422)
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L423-L448)
章节来源
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L1-L1082)
### 基础数据组件(Departments)
- 角色定位
- 容器组件:负责列表查询、分页、新增/编辑弹窗、状态切换与树形选择。
- 设计要点
- 搜索条件与分页参数传递至 API;树形选择使用树形数据;状态变更即时同步。
- 边界与接口
- 输入:搜索条件、分页参数;输出:表格数据、树形数据、提交结果。
- 复用策略
- 将 CRUD API 调用封装为独立函数;对表单校验与提交流程进行单元测试。
章节来源
- [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
### 考核管理组件(Assessments)
- 角色定位
- 容器组件:负责列表筛选、分页、批量创建、状态流转(提交/审核/确认)。
- 设计要点
- 多条件筛选与分页;批量创建弹窗;根据状态显示不同操作按钮。
- 边界与接口
- 输入:筛选条件、分页参数;输出:列表数据、批量创建结果。
- 复用策略
- 将状态标签映射与分数等级样式抽离为工具;对状态流转流程进行集成测试。
章节来源
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
### 考核详情组件(AssessmentDetail)
- 角色定位
- 容器组件:负责详情展示、草稿编辑、状态流转(保存/提交/审核/确认)。
- 设计要点
- 根据状态决定可编辑字段与操作按钮;状态标签与类型标签映射。
- 边界与接口
- 输入:路由参数(id);输出:详情数据、状态更新结果。
- 复用策略
- 将状态与类型映射封装为纯函数;对详情加载与状态更新进行单元测试。
章节来源
- [frontend/src/views/assessment/AssessmentDetail.vue](file://frontend/src/views/assessment/AssessmentDetail.vue#L1-L257)
### 状态管理(Pinia Store)
- 用户 Store(useUserStore)
- 负责登录、获取用户信息、登出与 Token 管理;与路由联动。
- 应用 Store(useAppStore)
- 负责侧边栏折叠状态与科室树加载。
- 导出聚合
- 在 stores/index.js 中集中导出,便于视图组件按需引入。
```mermaid
classDiagram
class UserStore {
+string token
+object userInfo
+login(username,password) Promise
+getUserInfo() Promise