提交文件
This commit is contained in:
442
.qoder/repowiki/zh/content/前端开发指南/Vue组件开发/Element Plus组件集成.md
Normal file
442
.qoder/repowiki/zh/content/前端开发指南/Vue组件开发/Element Plus组件集成.md
Normal file
@@ -0,0 +1,442 @@
|
||||
# Element Plus组件集成
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [package.json](file://frontend/package.json)
|
||||
- [main.js](file://frontend/src/main.js)
|
||||
- [vite.config.js](file://frontend/vite.config.js)
|
||||
- [App.vue](file://frontend/src/App.vue)
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue)
|
||||
- [Menus.vue](file://frontend/src/views/system/Menus.vue)
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue)
|
||||
- [Staff.vue](file://frontend/src/views/basic/Staff.vue)
|
||||
- [main.scss](file://frontend/src/assets/main.scss)
|
||||
- [menu.js](file://frontend/src/api/menu.js)
|
||||
- [request.js](file://frontend/src/api/request.js)
|
||||
- [router/index.js](file://frontend/src/router/index.js)
|
||||
- [stores/app.js](file://frontend/src/stores/app.js)
|
||||
- [stores/user.js](file://frontend/src/stores/user.js)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
本指南专注于Element Plus组件在医院绩效系统前端中的集成与使用。项目采用Vue 3 + Element Plus + Pinia + Vue Router的技术栈,实现了完整的组件化UI解决方案。本文将详细说明Element Plus的安装配置、按需导入和全局配置,涵盖表格、表单、对话框、导航菜单等常用组件的使用方法,并提供样式定制、主题配置和响应式布局的最佳实践。
|
||||
|
||||
## 项目结构
|
||||
前端项目采用模块化组织方式,Element Plus相关配置集中在入口文件和全局样式中:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "前端应用结构"
|
||||
A[main.js 应用入口] --> B[ElementPlus 全局配置]
|
||||
A --> C[Pinia 状态管理]
|
||||
A --> D[Vue Router 路由]
|
||||
A --> E[全局样式]
|
||||
F[App.vue 根组件] --> G[el-config-provider 国际化]
|
||||
F --> H[router-view 视图渲染]
|
||||
I[视图组件] --> J[Element Plus 组件]
|
||||
I --> K[业务逻辑]
|
||||
end
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [App.vue](file://frontend/src/App.vue#L1-L17)
|
||||
|
||||
**章节来源**
|
||||
- [package.json](file://frontend/package.json#L1-L27)
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
|
||||
## 核心组件
|
||||
项目中广泛使用了Element Plus的核心UI组件,包括表格、表单、对话框、菜单导航等:
|
||||
|
||||
### 安装与配置
|
||||
项目通过npm安装Element Plus及其图标库,配置方式如下:
|
||||
|
||||
- **依赖安装**: 在package.json中声明element-plus和@element-plus/icons-vue
|
||||
- **全局引入**: 在main.js中全局注册ElementPlus组件
|
||||
- **图标注册**: 自动注册所有Element Plus图标组件
|
||||
- **国际化**: 设置中文语言环境
|
||||
|
||||
### 组件使用模式
|
||||
项目采用统一的组件使用模式:
|
||||
- 所有页面组件都使用`<script setup>`语法
|
||||
- 通过`ElMessage`和`ElMessageBox`进行消息提示
|
||||
- 使用`v-loading`实现加载状态管理
|
||||
- 通过`ref`和`reactive`管理组件状态
|
||||
|
||||
**章节来源**
|
||||
- [package.json](file://frontend/package.json#L11-L20)
|
||||
- [main.js](file://frontend/src/main.js#L3-L21)
|
||||
- [App.vue](file://frontend/src/App.vue#L2-L4)
|
||||
|
||||
## 架构概览
|
||||
系统采用分层架构设计,Element Plus组件贯穿整个前端应用:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "表现层"
|
||||
A[Layout.vue 主布局]
|
||||
B[Menus.vue 菜单管理]
|
||||
C[Departments.vue 科室管理]
|
||||
D[Staff.vue 员工管理]
|
||||
end
|
||||
subgraph "组件层"
|
||||
E[el-menu 导航菜单]
|
||||
F[el-table 数据表格]
|
||||
G[el-form 表单组件]
|
||||
H[el-dialog 对话框]
|
||||
I[el-pagination 分页器]
|
||||
end
|
||||
subgraph "数据层"
|
||||
J[API 层]
|
||||
K[Pinia Store]
|
||||
L[后端服务]
|
||||
end
|
||||
A --> E
|
||||
B --> F
|
||||
B --> G
|
||||
B --> H
|
||||
C --> F
|
||||
C --> I
|
||||
D --> F
|
||||
D --> I
|
||||
E --> K
|
||||
F --> J
|
||||
G --> J
|
||||
H --> J
|
||||
I --> J
|
||||
J --> L
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue#L10-L24)
|
||||
- [Menus.vue](file://frontend/src/views/system/Menus.vue#L12-L51)
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L17-L54)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 导航菜单组件 (el-menu)
|
||||
导航菜单是系统的核心组件,实现了完整的侧边栏导航功能:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as 用户
|
||||
participant M as Menu组件
|
||||
participant S as Store
|
||||
participant A as API
|
||||
U->>M : 点击菜单项
|
||||
M->>S : 更新活动状态
|
||||
M->>A : 加载菜单数据
|
||||
A-->>M : 返回菜单树
|
||||
M->>M : 渲染菜单项
|
||||
M-->>U : 显示子菜单
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue#L86-L124)
|
||||
- [router/index.js](file://frontend/src/router/index.js#L104-L113)
|
||||
|
||||
菜单组件的关键特性:
|
||||
- 支持折叠/展开功能
|
||||
- 动态加载菜单树
|
||||
- 集成路由跳转
|
||||
- 响应式布局适配
|
||||
|
||||
**章节来源**
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue#L10-L25)
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue#L86-L124)
|
||||
|
||||
### 表格组件 (el-table)
|
||||
表格组件在多个业务页面中广泛应用,提供了完整的数据展示和操作功能:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[表格初始化] --> B[加载数据]
|
||||
B --> C{数据加载状态}
|
||||
C --> |成功| D[渲染表格]
|
||||
C --> |失败| E[显示错误信息]
|
||||
D --> F[用户交互]
|
||||
F --> G[编辑操作]
|
||||
F --> H[删除操作]
|
||||
G --> I[打开编辑对话框]
|
||||
H --> J[确认删除对话框]
|
||||
I --> K[表单验证]
|
||||
K --> L[提交更新]
|
||||
J --> M[执行删除]
|
||||
L --> N[刷新表格]
|
||||
M --> N
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L168-L181)
|
||||
- [Menus.vue](file://frontend/src/views/system/Menus.vue#L144-L152)
|
||||
|
||||
表格组件的核心功能:
|
||||
- 支持树形表格展示
|
||||
- 集成分页功能
|
||||
- 实现行内编辑
|
||||
- 提供批量操作
|
||||
|
||||
**章节来源**
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L17-L54)
|
||||
- [Menus.vue](file://frontend/src/views/system/Menus.vue#L12-L51)
|
||||
|
||||
### 表单组件 (el-form)
|
||||
表单组件提供了完整的数据输入和验证功能:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class FormComponent {
|
||||
+form : ReactiveObject
|
||||
+rules : Object
|
||||
+loading : Ref<boolean>
|
||||
+validate() : Promise<boolean>
|
||||
+handleSubmit() : Promise<void>
|
||||
+resetForm() : void
|
||||
}
|
||||
class FormItem {
|
||||
+prop : string
|
||||
+label : string
|
||||
+required : boolean
|
||||
+validator : Function
|
||||
}
|
||||
class ValidationRule {
|
||||
+required : boolean
|
||||
+message : string
|
||||
+trigger : string
|
||||
}
|
||||
FormComponent --> FormItem : "包含"
|
||||
FormItem --> ValidationRule : "使用"
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L127-L141)
|
||||
- [Menus.vue](file://frontend/src/views/system/Menus.vue#L125-L142)
|
||||
|
||||
表单组件的关键特性:
|
||||
- 支持多种输入控件
|
||||
- 实时表单验证
|
||||
- 条件渲染
|
||||
- 动态表单字段
|
||||
|
||||
**章节来源**
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L57-L99)
|
||||
- [Menus.vue](file://frontend/src/views/system/Menus.vue#L60-L102)
|
||||
|
||||
### 对话框组件 (el-dialog)
|
||||
对话框组件用于实现模态窗口的创建和编辑功能:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as 用户
|
||||
participant D as Dialog组件
|
||||
participant F as Form组件
|
||||
participant V as 验证器
|
||||
U->>D : 点击添加/编辑按钮
|
||||
D->>D : 打开对话框
|
||||
D->>F : 初始化表单数据
|
||||
U->>F : 输入表单数据
|
||||
F->>V : 触发表单验证
|
||||
V-->>F : 返回验证结果
|
||||
F-->>D : 显示验证错误
|
||||
U->>D : 点击确定按钮
|
||||
D->>D : 提交表单
|
||||
D-->>U : 关闭对话框并刷新数据
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L199-L211)
|
||||
- [Menus.vue](file://frontend/src/views/system/Menus.vue#L163-L179)
|
||||
|
||||
对话框组件的功能特点:
|
||||
- 支持自定义宽度
|
||||
- 阻止点击遮罩关闭
|
||||
- 集成表单验证
|
||||
- 实现数据提交
|
||||
|
||||
**章节来源**
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L57-L99)
|
||||
- [Menus.vue](file://frontend/src/views/system/Menus.vue#L54-L108)
|
||||
|
||||
### 分页组件 (el-pagination)
|
||||
分页组件提供了完整的数据分页功能:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[用户操作] --> B{分页操作类型}
|
||||
B --> |改变页码| C[更新当前页]
|
||||
B --> |改变每页大小| D[更新页大小]
|
||||
C --> E[触发数据加载]
|
||||
D --> E
|
||||
E --> F[调用API获取数据]
|
||||
F --> G[更新表格数据]
|
||||
G --> H[更新分页状态]
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L46-L54)
|
||||
|
||||
分页组件的核心功能:
|
||||
- 支持多种布局模式
|
||||
- 集成数据加载
|
||||
- 实现状态同步
|
||||
|
||||
**章节来源**
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L46-L54)
|
||||
|
||||
## 依赖关系分析
|
||||
|
||||
### 组件依赖关系
|
||||
项目中Element Plus组件的使用呈现清晰的层次结构:
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "应用层"
|
||||
A[main.js] --> B[App.vue]
|
||||
B --> C[Layout.vue]
|
||||
end
|
||||
subgraph "业务组件层"
|
||||
C --> D[Menus.vue]
|
||||
C --> E[Departments.vue]
|
||||
C --> F[Staff.vue]
|
||||
end
|
||||
subgraph "Element Plus组件层"
|
||||
D --> G[el-table]
|
||||
D --> H[el-form]
|
||||
D --> I[el-dialog]
|
||||
E --> G
|
||||
E --> J[el-pagination]
|
||||
F --> G
|
||||
F --> J
|
||||
C --> K[el-menu]
|
||||
C --> L[el-breadcrumb]
|
||||
C --> M[el-dropdown]
|
||||
end
|
||||
subgraph "工具层"
|
||||
N[main.scss] --> O[全局样式]
|
||||
P[request.js] --> Q[API封装]
|
||||
R[router/index.js] --> S[路由配置]
|
||||
end
|
||||
G --> O
|
||||
H --> O
|
||||
I --> O
|
||||
J --> O
|
||||
K --> O
|
||||
L --> O
|
||||
M --> O
|
||||
```
|
||||
|
||||
**图表来源**
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue#L1-L71)
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L101)
|
||||
|
||||
### 外部依赖分析
|
||||
项目对外部依赖的管理策略:
|
||||
|
||||
| 依赖类型 | 版本范围 | 用途 | 配置方式 |
|
||||
|---------|----------|------|----------|
|
||||
| element-plus | ^2.5.3 | UI组件库 | 全局引入 |
|
||||
| @element-plus/icons-vue | ^2.3.1 | 图标组件 | 自动注册 |
|
||||
| vue | ^3.4.15 | 核心框架 | 通过Vite管理 |
|
||||
| vue-router | ^4.2.5 | 路由管理 | 插件注册 |
|
||||
| pinia | ^2.1.7 | 状态管理 | 插件注册 |
|
||||
|
||||
**章节来源**
|
||||
- [package.json](file://frontend/package.json#L11-L20)
|
||||
- [main.js](file://frontend/src/main.js#L3-L21)
|
||||
|
||||
## 性能考虑
|
||||
基于项目实际实现,以下是Element Plus组件使用的性能优化建议:
|
||||
|
||||
### 按需导入配置
|
||||
虽然项目采用全局导入方式,但推荐在大型项目中使用按需导入以减少包体积:
|
||||
|
||||
```javascript
|
||||
// 推荐的按需导入配置
|
||||
import { ElTable, ElTableColumn, ElButton } from 'element-plus'
|
||||
```
|
||||
|
||||
### 虚拟滚动应用
|
||||
对于大量数据的表格,建议实现虚拟滚动:
|
||||
|
||||
```javascript
|
||||
// 虚拟滚动配置示例
|
||||
<el-table virtual-scroll="{ itemHeight: 48, container: '.table-container' }">
|
||||
```
|
||||
|
||||
### 组件懒加载
|
||||
利用Vue的动态导入实现组件懒加载:
|
||||
|
||||
```javascript
|
||||
const HeavyComponent = () => import('@/components/HeavyComponent.vue')
|
||||
```
|
||||
|
||||
### 样式优化
|
||||
项目已实现基础的样式优化,建议进一步优化:
|
||||
|
||||
- 合理使用CSS变量
|
||||
- 避免深层嵌套选择器
|
||||
- 使用scoped样式减少样式冲突
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 常见问题诊断
|
||||
基于项目实现,以下是Element Plus组件使用中可能遇到的问题及解决方案:
|
||||
|
||||
#### 国际化配置问题
|
||||
**问题症状**: 组件显示英文或乱码
|
||||
**解决方案**: 确保在应用入口正确配置语言包
|
||||
|
||||
#### 图标不显示问题
|
||||
**问题症状**: 自定义图标无法显示
|
||||
**解决方案**: 检查图标注册是否正确执行
|
||||
|
||||
#### 表单验证失效
|
||||
**问题症状**: 表单验证规则不生效
|
||||
**解决方案**: 确认表单引用和验证规则配置正确
|
||||
|
||||
#### 数据加载异常
|
||||
**问题症状**: 表格数据无法加载
|
||||
**解决方案**: 检查API接口和数据格式
|
||||
|
||||
**章节来源**
|
||||
- [main.js](file://frontend/src/main.js#L14-L17)
|
||||
- [request.js](file://frontend/src/api/request.js#L15-L26)
|
||||
|
||||
### 调试技巧
|
||||
- 使用浏览器开发者工具检查组件属性
|
||||
- 利用Vue DevTools观察组件状态变化
|
||||
- 通过console输出调试信息
|
||||
- 检查网络面板确认API请求状态
|
||||
|
||||
## 结论
|
||||
本项目成功集成了Element Plus组件库,实现了完整的医院绩效管理系统前端界面。通过全局配置和统一的组件使用模式,项目展现了良好的代码组织和用户体验。
|
||||
|
||||
### 最佳实践总结
|
||||
1. **统一配置**: 在应用入口集中配置Element Plus
|
||||
2. **组件复用**: 通过组合式API实现组件逻辑复用
|
||||
3. **状态管理**: 使用Pinia管理全局状态
|
||||
4. **样式规范**: 通过SCSS实现一致的视觉风格
|
||||
5. **错误处理**: 统一的消息提示和错误处理机制
|
||||
|
||||
### 未来改进建议
|
||||
1. 考虑实现按需导入以优化包体积
|
||||
2. 为大数据量场景添加虚拟滚动支持
|
||||
3. 增强组件的可访问性支持
|
||||
4. 实现更完善的主题定制系统
|
||||
5. 添加组件性能监控和优化
|
||||
|
||||
通过持续的优化和改进,该项目的Element Plus组件集成将为用户提供更加流畅和专业的使用体验。
|
||||
@@ -0,0 +1,302 @@
|
||||
# Vue Composition API开发
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [frontend/src/main.js](file://frontend/src/main.js)
|
||||
- [frontend/src/App.vue](file://frontend/src/App.vue)
|
||||
- [frontend/package.json](file://frontend/package.json)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js)
|
||||
- [frontend/src/api/index.js](file://frontend/src/api/index.js)
|
||||
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue)
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue)
|
||||
- [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 引言
|
||||
本指南面向使用 Vue 3 Composition API 的开发者,围绕 setup 函数、响应式数据 ref 与 reactive 的区别与场景、计算属性 computed、监听器 watch 与 watchEffect、生命周期钩子(如 onMounted、onUnmounted 等)、组合函数(composables)的设计与复用、以及从 Options API 迁移到 Composition API 的最佳实践展开。文档结合仓库中的真实组件与状态管理,提供可操作的建议与图示。
|
||||
|
||||
## 项目结构
|
||||
前端采用 Vite + Vue 3 + Pinia + Element Plus 技术栈,路由基于 vue-router。项目入口在 main.js 中创建应用实例并挂载;App.vue 作为根组件包裹路由视图;views 下按功能模块组织页面;stores 提供全局状态;router 定义导航与守卫;api 汇聚接口模块。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A["main.js<br/>创建应用实例"] --> B["App.vue<br/>根组件"]
|
||||
B --> C["router/index.js<br/>路由与守卫"]
|
||||
C --> D["views/*<br/>页面组件"]
|
||||
A --> E["stores/*<br/>Pinia Store"]
|
||||
A --> F["api/*<br/>接口聚合"]
|
||||
A --> G["Element Plus<br/>UI库"]
|
||||
A --> H["Vite 配置<br/>代理/别名"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [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/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [frontend/src/api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
|
||||
章节来源
|
||||
- [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/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [frontend/src/api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
|
||||
## 核心组件
|
||||
- 应用入口与插件注册:在 main.js 中创建应用、注册 Element Plus、Pinia、路由,并挂载到 DOM。
|
||||
- 根组件 App.vue:提供语言环境配置,承载路由视图。
|
||||
- 路由与守卫:router/index.js 定义多级菜单路由与登录守卫。
|
||||
- 全局状态:stores/app.js 与 stores/user.js 使用组合式 Store(defineStore 返回函数式 Store),内部使用 ref 管理响应式状态。
|
||||
- 页面组件:views 下包含 Dashboard、Layout、Assessments、Departments 等,广泛使用 setup 函数、ref、reactive、computed、watch/watchEffect、生命周期钩子与 API 调用。
|
||||
|
||||
章节来源
|
||||
- [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/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
|
||||
## 架构总览
|
||||
下图展示从入口到页面组件的数据与控制流:main.js 初始化应用与插件;App.vue 渲染路由视图;Layout.vue 作为布局容器,调用 stores 与 API;具体业务页面(如 Dashboard、Assessments、Departments)在 setup 中声明响应式数据、计算属性、监听器与生命周期钩子,并发起 API 请求。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant M as "main.js"
|
||||
participant APP as "App.vue"
|
||||
participant R as "router/index.js"
|
||||
participant L as "Layout.vue"
|
||||
participant P as "页面组件(Dashboard/Assessments/Departments)"
|
||||
participant S as "stores/*"
|
||||
participant API as "api/*"
|
||||
M->>APP : 创建并挂载应用
|
||||
APP->>R : 注入路由
|
||||
R-->>L : 渲染布局
|
||||
L->>S : 读取/写入全局状态
|
||||
L->>API : 加载菜单树
|
||||
P->>S : 访问全局状态
|
||||
P->>API : 发起业务请求
|
||||
API-->>P : 返回数据
|
||||
P-->>L : 渲染视图
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [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/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L1-L1082)
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
|
||||
- [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [frontend/src/api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### setup 函数与响应式数据:ref vs reactive
|
||||
- 在页面组件中,setup 函数用于声明响应式数据与逻辑。常见模式:
|
||||
- 使用 ref 声明基本类型或简单对象,如字符串、数字、布尔值、DOM 引用等。
|
||||
- 使用 reactive 声明复杂对象(如表单、分页参数),便于在模板中直接访问其属性。
|
||||
- 示例组件中的使用:
|
||||
- Dashboard.vue:大量使用 ref(如图表容器引用、周期选择、统计数据对象)与 reactive(如搜索条件、分页参数)。
|
||||
- Assessments.vue:同时使用 ref(loading、对话框可见性)与 reactive(搜索表单、分页、批量创建表单)。
|
||||
- Departments.vue:同样混合使用 ref 与 reactive。
|
||||
- 设计建议:
|
||||
- 对于简单标量或需要重新赋值的对象,优先使用 ref。
|
||||
- 对于复杂对象且不需要整体替换,优先使用 reactive。
|
||||
- 在模板中频繁访问深层属性时,reactive 更直观;需要整体替换或跨函数传递引用时,ref 更合适。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L225-L421)
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L116-L293)
|
||||
- [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L103-L272)
|
||||
|
||||
### 计算属性 computed
|
||||
- computed 用于派生状态,自动追踪依赖并在依赖变化时重新计算。
|
||||
- 示例:
|
||||
- Dashboard.vue 中的 assessedRate(完成率)与 hasAlerts(是否存在预警)均通过 computed 声明,避免在模板中重复计算。
|
||||
- 最佳实践:
|
||||
- 仅依赖响应式数据;避免在 getter 内部修改状态。
|
||||
- 复杂计算尽量拆分为多个小的 computed,提升可维护性。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L306-L315)
|
||||
|
||||
### 监听器 watch 与 watchEffect
|
||||
- watch:监听特定响应式数据的变化,适合需要在变化时执行副作用(如发起请求、更新图表)。
|
||||
- 示例:Dashboard.vue 中对周期选择(chartPeriod、financePeriod、rankingPeriod)的监听,触发对应数据加载与图表更新。
|
||||
- watchEffect:自动追踪其执行期间访问到的响应式数据,无需显式声明监听目标。
|
||||
- 示例:Dashboard.vue 中在加载关键指标后使用 nextTick,再更新仪表盘图表,体现了 watchEffect 的自动依赖追踪特性。
|
||||
- 最佳实践:
|
||||
- watch 适用于明确的目标与旧值/新值对比;watchEffect 适用于“只要相关数据变化就刷新”的场景。
|
||||
- 注意清理副作用(如在组件卸载时取消订阅或清空定时器)。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L362-L421)
|
||||
|
||||
### 生命周期钩子:onMounted、onUnmounted 等
|
||||
- onMounted:在组件挂载后执行初始化逻辑,如加载菜单、初始化图表、绑定窗口 resize 事件等。
|
||||
- Layout.vue:在 onMounted 中加载菜单树。
|
||||
- Dashboard.vue:在 onMounted 中初始化多个 ECharts 实例并绑定 resize 事件。
|
||||
- onUnmounted:用于清理副作用(如移除事件监听、销毁图表实例)。
|
||||
- Dashboard.vue:在组件卸载时应移除 window.resize 监听与图表实例,避免内存泄漏。
|
||||
- 最佳实践:
|
||||
- 将副作用集中在 onMounted 中启动,在 onUnmounted 中统一清理。
|
||||
- 对于需要等待 DOM 更新后再执行的逻辑,配合 nextTick 使用。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L122-L124)
|
||||
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L423-L448)
|
||||
|
||||
### 组合函数(Composables)设计与复用
|
||||
- 当前项目中,全局状态通过 Pinia 的组合式 Store(函数式 Store)实现,内部使用 ref 管理状态,对外暴露方法与状态。
|
||||
- app.js:封装侧边栏折叠状态与科室树加载。
|
||||
- user.js:封装登录、登出、用户信息获取。
|
||||
- 设计模式建议:
|
||||
- 将可复用的逻辑(如图表初始化、分页加载、表单校验)抽象为独立的 Composable,返回 ref 或 reactive 数据与方法。
|
||||
- 在组件中通过 import 使用这些 Composable,保持 setup 的简洁与关注点分离。
|
||||
- 状态共享:
|
||||
- 使用 Pinia Store 在组件间共享状态;对于轻量状态,也可通过 props/$emit 或 provide/inject 实现。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
|
||||
### 从 Options API 迁移到 Composition API 的最佳实践
|
||||
- 迁移步骤建议:
|
||||
- 将 data 中的每个字段改为 setup 中的 ref 或 reactive。
|
||||
- 将 methods 中的方法迁移到 setup 中的普通函数;将计算属性迁移到 computed。
|
||||
- 将生命周期钩子迁移到 onMounted/onUpdated 等。
|
||||
- 将 watch 改为 watch 或 watchEffect。
|
||||
- 将混入(mixins)替换为组合函数(Composable)。
|
||||
- 项目中的迁移体现:
|
||||
- 各页面组件(Dashboard、Assessments、Departments)已全面使用 setup 函数与组合式 API。
|
||||
- 菜单加载与图表初始化等逻辑集中在 setup 中,便于测试与复用。
|
||||
- 注意事项:
|
||||
- 避免在 setup 中进行过多同步阻塞操作;异步请求放在 onMounted 中。
|
||||
- 对于需要在模板中直接使用的函数,保持箭头函数或普通函数形式,确保 this 不丢失(在 setup 中不会出现 this)。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L225-L421)
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L116-L293)
|
||||
- [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L103-L272)
|
||||
|
||||
### 组件重构示例:Dashboard(从 Options API 到 Composition API)
|
||||
- 重构要点:
|
||||
- 将 data 中的统计、排名、趋势、图表容器等状态迁移为 ref/refs 与 reactive。
|
||||
- 将 methods 中的加载函数(如 loadStats、loadRanking、loadTrendData 等)迁移为普通函数。
|
||||
- 将 computed 中的 assessedRate、hasAlerts 迁移为 computed。
|
||||
- 将 mounted 中的图表初始化与事件绑定迁移至 onMounted,并在 onUnmounted 中清理。
|
||||
- 将 watch 中的周期切换逻辑迁移为 watch 或 watchEffect。
|
||||
- 重构收益:
|
||||
- setup 中逻辑集中,便于阅读与测试。
|
||||
- 计算属性与监听器自动追踪依赖,减少手动维护。
|
||||
- 与组合函数(Composable)结合,进一步提升复用性。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L225-L421)
|
||||
|
||||
## 依赖分析
|
||||
- 依赖关系概览:
|
||||
- main.js 依赖 Vue、Pinia、Element Plus、路由与样式。
|
||||
- App.vue 依赖 Element Plus 国际化配置。
|
||||
- router/index.js 依赖路由与守卫。
|
||||
- stores/* 依赖 Pinia 与 API。
|
||||
- views/* 依赖 Element Plus、ECharts、API 与 stores。
|
||||
- 外部依赖版本参考:
|
||||
- Vue 3、Pinia、Element Plus、vue-router、axios、echarts、dayjs 等。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
MJS["main.js"] --> V["vue"]
|
||||
MJS --> P["pinia"]
|
||||
MJS --> EP["element-plus"]
|
||||
MJS --> VR["vue-router"]
|
||||
MJS --> AX["axios"]
|
||||
MJS --> SCSS["sass"]
|
||||
MJS --> ECH["echarts"]
|
||||
APP["App.vue"] --> EP
|
||||
ROUTER["router/index.js"] --> VR
|
||||
STORE_APP["stores/app.js"] --> P
|
||||
STORE_USER["stores/user.js"] --> P
|
||||
VIEWS["views/*"] --> EP
|
||||
VIEWS --> ECH
|
||||
VIEWS --> API["api/*"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [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/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [frontend/src/api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
- [frontend/package.json](file://frontend/package.json#L11-L25)
|
||||
|
||||
章节来源
|
||||
- [frontend/package.json](file://frontend/package.json#L11-L25)
|
||||
|
||||
## 性能考虑
|
||||
- 图表渲染性能:
|
||||
- 在 Dashboard 中,多个 ECharts 实例在 onMounted 中初始化,应在 onUnmounted 中销毁实例并移除 resize 监听,避免内存泄漏。
|
||||
- 对于大数据量图表,建议在 watch 中按需更新选项,避免全量 setOption 导致重绘开销。
|
||||
- 状态更新与重渲染:
|
||||
- 使用 computed 缓存派生结果,减少不必要的重渲染。
|
||||
- 将复杂计算拆分为多个小的 computed,降低依赖范围。
|
||||
- API 请求节流:
|
||||
- 对于高频变更(如日期选择、筛选条件),可在 watch 中加入防抖策略,减少请求次数。
|
||||
- 路由懒加载:
|
||||
- 路由组件已使用动态导入,有助于首屏加载性能。
|
||||
|
||||
## 故障排查指南
|
||||
- 登录与路由守卫:
|
||||
- 若进入受保护页面被重定向到登录页,检查本地存储 token 是否存在;路由守卫会根据 token 决定是否放行。
|
||||
- 图表不显示或空白:
|
||||
- 确认 onMounted 中已初始化图表实例并在数据就绪后 setOption;若使用 nextTick,请确保在数据更新后再执行更新逻辑。
|
||||
- 菜单加载失败:
|
||||
- Layout.vue 中的菜单加载失败会回退到默认菜单;检查后端接口与网络请求状态。
|
||||
- 状态不同步:
|
||||
- Pinia Store 中的状态更新需通过 ref.value 修改;确保在组件中正确读取与写入。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L104-L113)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L86-L116)
|
||||
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L423-L448)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L14-L22)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L34-L39)
|
||||
|
||||
## 结论
|
||||
本项目已全面采用 Vue 3 Composition API,结合 Pinia 实现状态管理,配合 Element Plus 与 ECharts 构建了功能完备的绩效管理系统前端。通过在 setup 中集中声明响应式数据、计算属性、监听器与生命周期钩子,提升了代码的可读性与可维护性。建议在后续开发中持续引入组合函数(Composable)以增强逻辑复用,并在图表与数据密集场景中优化渲染与请求策略,进一步提升用户体验与性能表现。
|
||||
|
||||
## 附录
|
||||
- 开发与构建命令:
|
||||
- dev:启动开发服务器
|
||||
- build:打包生产资源
|
||||
- preview:预览生产构建
|
||||
- 代理配置:
|
||||
- 前端开发时将 /api 代理到后端服务地址,便于联调。
|
||||
|
||||
章节来源
|
||||
- [frontend/package.json](file://frontend/package.json#L6-L10)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L14-L19)
|
||||
455
.qoder/repowiki/zh/content/前端开发指南/Vue组件开发/Vue组件开发.md
Normal file
455
.qoder/repowiki/zh/content/前端开发指南/Vue组件开发/Vue组件开发.md
Normal file
@@ -0,0 +1,455 @@
|
||||
# Vue组件开发
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [frontend/src/main.js](file://frontend/src/main.js)
|
||||
- [frontend/package.json](file://frontend/package.json)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js)
|
||||
- [frontend/src/App.vue](file://frontend/src/App.vue)
|
||||
- [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/stores/app.js](file://frontend/src/stores/app.js)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js)
|
||||
- [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/assets/main.scss](file://frontend/src/assets/main.scss)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [组件详解](#组件详解)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本指南面向使用 Vue 3 Composition API 的前端开发者,结合仓库中的实际代码,系统讲解组件开发的关键实践:响应式数据与生命周期、组件间通信、Element Plus 集成、自定义组件与复用策略、设计模式与代码组织、测试与调试、性能优化以及 API 调用封装与错误处理。文中所有分析均基于仓库中的真实文件与实现。
|
||||
|
||||
## 项目结构
|
||||
前端采用 Vite + Vue 3 + Pinia + Element Plus 技术栈,路由基于 vue-router,API 层统一通过 axios 封装。整体目录按功能域划分,便于组件与业务模块化组织。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A["入口 main.js<br/>创建应用/注册插件"] --> B["根组件 App.vue<br/>国际化配置"]
|
||||
A --> C["路由 router/index.js<br/>动态导入视图组件"]
|
||||
A --> D["状态 stores/*<br/>Pinia Store"]
|
||||
A --> E["API 层 api/*<br/>Axios 封装与接口"]
|
||||
A --> F["视图 views/*<br/>页面级组件"]
|
||||
A --> G["样式 assets/main.scss<br/>全局样式与主题变量"]
|
||||
F --> H["布局 Layout.vue<br/>侧边栏/头部/面包屑"]
|
||||
F --> I["登录 Login.vue<br/>表单校验/登录流程"]
|
||||
F --> J["基础数据 Departments.vue<br/>表格/分页/对话框"]
|
||||
F --> K["考核管理 Assessments.vue<br/>树形筛选/状态标签/批量创建"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [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/views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
|
||||
- [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [frontend/src/assets/main.scss](file://frontend/src/assets/main.scss#L1-L186)
|
||||
|
||||
章节来源
|
||||
- [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/package.json](file://frontend/package.json#L1-L27)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
|
||||
## 核心组件
|
||||
- 应用入口与插件注册:创建应用实例、注册 Element Plus、图标、Pinia、路由;全局样式引入。
|
||||
- 根组件:提供 Element Plus 国际化上下文。
|
||||
- 路由系统:定义页面级路由、懒加载视图、路由守卫(鉴权与标题设置)。
|
||||
- 状态管理:Pinia Store(应用状态与用户状态),集中管理 token、菜单树、侧边栏折叠等。
|
||||
- API 层:Axios 实例封装,统一请求/响应拦截器,错误提示与自动登出。
|
||||
- 视图组件:布局、登录、基础数据、考核管理等页面组件,展示 Composition API 与 Element Plus 的典型用法。
|
||||
|
||||
章节来源
|
||||
- [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#L104-L113)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
|
||||
## 架构总览
|
||||
下图展示了从前端入口到页面组件的数据流与交互关系,体现 Composition API、Pinia、Element Plus 与 API 层的协作。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "运行时"
|
||||
M["main.js<br/>应用初始化"] --> R["router/index.js<br/>路由守卫/导航"]
|
||||
M --> P["Pinia Stores<br/>useAppStore/useUserStore"]
|
||||
M --> EP["Element Plus<br/>组件/图标/国际化"]
|
||||
end
|
||||
subgraph "页面层"
|
||||
L["views/Layout.vue<br/>侧边栏/头部/面包屑"]
|
||||
LG["views/Login.vue<br/>登录表单/消息提示"]
|
||||
D["views/basic/Departments.vue<br/>表格/分页/对话框"]
|
||||
A["views/assessment/Assessments.vue<br/>树形筛选/批量创建"]
|
||||
end
|
||||
subgraph "数据层"
|
||||
API["api/request.js<br/>Axios 实例/拦截器"]
|
||||
DEPT["api/department.js<br/>科室接口"]
|
||||
ASSESS["api/assessment.js<br/>考核接口"]
|
||||
end
|
||||
M --> L
|
||||
M --> LG
|
||||
M --> D
|
||||
M --> A
|
||||
L --> P
|
||||
LG --> P
|
||||
D --> DEPT
|
||||
A --> ASSESS
|
||||
DEPT --> API
|
||||
ASSESS --> API
|
||||
API --> R
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [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/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
|
||||
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
|
||||
- [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L1-L50)
|
||||
|
||||
## 组件详解
|
||||
|
||||
### 布局组件 Layout.vue
|
||||
- 功能要点
|
||||
- 侧边栏菜单:根据后端返回的菜单树渲染,支持折叠切换与图标动态绑定。
|
||||
- 头部区域:面包屑、用户下拉菜单、登出。
|
||||
- 内容区:路由视图过渡动画。
|
||||
- 数据加载:首次挂载时异步加载菜单树,失败时回退默认菜单。
|
||||
- 关键实现模式
|
||||
- Composition API:使用 ref、reactive、onMounted 管理状态与生命周期。
|
||||
- Element Plus:el-menu、el-breadcrumb、el-dropdown、el-icon、el-tree-select 等。
|
||||
- 状态与 API:Pinia 应用状态用于侧边栏折叠;菜单树通过 API 获取。
|
||||
- 设计建议
|
||||
- 菜单树转换逻辑可抽离为工具函数,提升可测试性。
|
||||
- 错误回退策略需与后端约定默认结构,避免空值处理分散。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["组件挂载"]) --> Load["加载菜单树"]
|
||||
Load --> Ok{"请求成功?"}
|
||||
Ok --> |是| Render["渲染菜单树"]
|
||||
Ok --> |否| Fallback["使用默认菜单"]
|
||||
Render --> End(["完成"])
|
||||
Fallback --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L86-L124)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
|
||||
|
||||
### 登录组件 Login.vue
|
||||
- 功能要点
|
||||
- 用户名/密码输入、表单校验、Enter 键触发登录。
|
||||
- 登录流程:调用用户 Store 的登录方法,成功后跳转首页,失败提示错误。
|
||||
- 加载态:按钮 loading 控制防止重复提交。
|
||||
- 关键实现模式
|
||||
- 表单校验:Element Plus el-form + validate。
|
||||
- 消息提示:ElMessage 成功/错误提示。
|
||||
- 路由跳转:vue-router 的 push。
|
||||
- 状态管理:Pinia 用户 Store 管理 token 与登录状态。
|
||||
- 设计建议
|
||||
- 将表单规则抽取为可复用的验证器,便于多组件共享。
|
||||
- 登录成功后的回调可抽象为通用钩子,减少重复逻辑。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant C as "Login.vue"
|
||||
participant S as "useUserStore"
|
||||
participant R as "router"
|
||||
U->>C : 输入用户名/密码并点击登录
|
||||
C->>C : 表单校验 validate()
|
||||
alt 校验通过
|
||||
C->>S : login(username, password)
|
||||
S-->>C : 返回布尔结果
|
||||
alt 登录成功
|
||||
C->>R : push("/")
|
||||
C->>C : 显示成功消息
|
||||
else 登录失败
|
||||
C->>C : 显示错误消息
|
||||
end
|
||||
else 校验失败
|
||||
C->>C : 不发起请求
|
||||
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/router/index.js](file://frontend/src/router/index.js#L104-L113)
|
||||
|
||||
章节来源
|
||||
- [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)
|
||||
|
||||
### 科室管理组件 Departments.vue
|
||||
- 功能要点
|
||||
- 查询条件:关键词、类型、分页参数。
|
||||
- 表格列:编码、名称、类型(标签)、层级、状态开关、创建时间。
|
||||
- 操作列:编辑、删除;状态变更即时更新。
|
||||
- 对话框:新增/编辑表单,树形上级选择、表单校验、提交。
|
||||
- 分页:el-pagination 支持页大小与当前页变更。
|
||||
- 关键实现模式
|
||||
- 表单与表格:Element Plus el-table、el-dialog、el-form、el-tree-select。
|
||||
- 状态与生命周期:ref/reactive 管理本地状态;onMounted 初始化加载。
|
||||
- API 调用:封装的部门接口,统一错误处理与消息提示。
|
||||
- 设计建议
|
||||
- 将“状态标签映射”与“日期格式化”抽离为纯函数,便于复用与测试。
|
||||
- 对话框表单校验失败时聚焦首个错误项,提升用户体验。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Init(["组件挂载"]) --> LoadList["加载科室列表"]
|
||||
Init --> LoadTree["加载科室树"]
|
||||
LoadList --> Done["渲染表格"]
|
||||
LoadTree --> Done
|
||||
Done --> Search["用户点击查询"]
|
||||
Search --> LoadList
|
||||
Done --> Edit["打开编辑对话框"]
|
||||
Edit --> Submit["提交表单校验"]
|
||||
Submit --> |通过| Save["调用新增/更新接口"]
|
||||
Submit --> |失败| Focus["提示并聚焦错误项"]
|
||||
Save --> Refresh["刷新列表与树"]
|
||||
Refresh --> Done
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L168-L271)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
|
||||
### 考核管理组件 Assessments.vue
|
||||
- 功能要点
|
||||
- 查询条件:所属科室(树形选择)、考核周期(月份)、状态筛选。
|
||||
- 表格列:姓名、科室、周期、总分、加权得分(带等级样式)、状态标签、创建时间。
|
||||
- 操作列:详情、提交、审核(通过/驳回)、确认。
|
||||
- 批量创建:弹窗选择科室、周期、指标集合,构造 URLSearchParams 发起请求。
|
||||
- 关键实现模式
|
||||
- 状态映射:状态标签与样式映射,分数等级样式。
|
||||
- 多源数据:同时加载科室树与有效指标,保证 UI 一致性。
|
||||
- 批量创建:URLSearchParams 处理重复查询参数,满足后端要求。
|
||||
- 设计建议
|
||||
- 将“状态标签映射”与“分数等级样式”抽取为独立工具,便于统一维护。
|
||||
- 批量创建前进行必填项校验,避免无效请求。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant C as "Assessments.vue"
|
||||
participant API as "assessment.js"
|
||||
participant REQ as "request.js(Axios)"
|
||||
participant R as "router"
|
||||
U->>C : 点击“批量创建”
|
||||
C->>C : 打开弹窗并清空表单
|
||||
U->>C : 填写科室/周期/指标
|
||||
C->>C : 校验必填项
|
||||
alt 校验通过
|
||||
C->>API : batchCreateAssessments(data)
|
||||
API->>REQ : POST /assessments/batch-create<br/>构造URLSearchParams
|
||||
REQ-->>API : 返回结果
|
||||
API-->>C : 结果
|
||||
C->>C : 显示成功消息并关闭弹窗
|
||||
C->>C : 刷新列表
|
||||
else 校验失败
|
||||
C->>C : 显示提示
|
||||
end
|
||||
U->>C : 点击“详情”
|
||||
C->>R : push(/assessments/ : id)
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L257-L286)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L39-L49)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L52-L56)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L1-L50)
|
||||
|
||||
### 状态管理与生命周期
|
||||
- 应用状态(useAppStore)
|
||||
- 管理侧边栏折叠状态与科室树数据,提供切换与加载方法。
|
||||
- 用户状态(useUserStore)
|
||||
- 管理 token、用户信息、登录/登出流程;登出后清理本地存储并跳转登录页。
|
||||
- 生命周期
|
||||
- 页面组件普遍在 onMounted 中发起初次数据加载;对话框打开时再加载必要数据(如树形选择)。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L122-L124)
|
||||
- [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L268-L271)
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L288-L292)
|
||||
|
||||
### 组件间通信与路由集成
|
||||
- Props 与事件
|
||||
- Element Plus 组件通过 v-model、事件(如 size-change、current-change)实现双向绑定与回调。
|
||||
- 插槽与作用域插槽
|
||||
- 表格列使用作用域插槽渲染标签、状态与格式化字段。
|
||||
- 路由与导航
|
||||
- 路由守卫统一处理登录态与页面标题;详情页通过动态路由参数跳转。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L104-L113)
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L223-L225)
|
||||
|
||||
### Element Plus 集成与自定义组件
|
||||
- 全局注册图标与组件
|
||||
- 在入口循环注册 Element Plus 图标,按需在组件中使用。
|
||||
- 国际化与主题
|
||||
- 根组件提供语言包;全局样式定义主题变量与通用组件样式。
|
||||
- 自定义组件开发建议
|
||||
- 将常用交互(如弹窗、树形选择、状态标签)封装为可复用组件,统一 props 与事件。
|
||||
- 保持组件单一职责,通过插槽扩展内容。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/main.js](file://frontend/src/main.js#L14-L17)
|
||||
- [frontend/src/App.vue](file://frontend/src/App.vue#L1-L9)
|
||||
- [frontend/src/assets/main.scss](file://frontend/src/assets/main.scss#L14-L26)
|
||||
|
||||
### API 调用封装与错误处理
|
||||
- Axios 实例
|
||||
- 统一 base URL、超时、请求头;自动注入 Authorization。
|
||||
- 响应拦截
|
||||
- 统一处理业务错误码、HTTP 状态码;401 自动清除 token 并跳转登录。
|
||||
- 接口封装
|
||||
- 按领域拆分接口文件(部门、考核),对特殊参数(如批量创建)进行 URLSearchParams 处理。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as "组件"
|
||||
participant API as "api/*"
|
||||
participant AX as "request.js(Axios)"
|
||||
participant BE as "后端"
|
||||
C->>API : 调用接口函数
|
||||
API->>AX : request.get/post/put/delete(...)
|
||||
AX->>BE : 发送请求(携带token)
|
||||
BE-->>AX : 返回响应
|
||||
AX->>AX : 响应拦截器校验
|
||||
alt 业务成功
|
||||
AX-->>API : 返回数据
|
||||
API-->>C : 返回结果
|
||||
else 业务失败/HTTP异常
|
||||
AX-->>API : 抛出错误并提示
|
||||
API-->>C : 捕获错误
|
||||
end
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L1-L50)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L1-L50)
|
||||
|
||||
## 依赖关系分析
|
||||
- 运行时依赖
|
||||
- Vue 3、vue-router、pinia、axios、element-plus、@element-plus/icons-vue、echarts、dayjs。
|
||||
- 构建与开发
|
||||
- Vite、@vitejs/plugin-vue、sass。
|
||||
- 代理与别名
|
||||
- Vite 代理 /api -> 后端 8000 端口;路径别名 @ 指向 src。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
P["package.json 依赖"] --> V["Vue 3"]
|
||||
P --> R["vue-router"]
|
||||
P --> S["pinia"]
|
||||
P --> X["axios"]
|
||||
P --> EP["element-plus"]
|
||||
P --> I["@element-plus/icons-vue"]
|
||||
P --> E["echarts"]
|
||||
P --> D["dayjs"]
|
||||
VC["vite.config.js"] --> A["@ 路径别名"]
|
||||
VC --> PX["/api 代理"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/package.json](file://frontend/package.json#L11-L25)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L7-L20)
|
||||
|
||||
章节来源
|
||||
- [frontend/package.json](file://frontend/package.json#L1-L27)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
|
||||
## 性能考量
|
||||
- 组件渲染
|
||||
- 使用 v-loading 在长列表加载时提供占位反馈,避免白屏。
|
||||
- 表格列使用作用域插槽渲染标签与状态,减少重复计算。
|
||||
- 状态与计算
|
||||
- 将映射表(状态/类型)定义为常量,避免每次渲染重新创建。
|
||||
- 网络请求
|
||||
- 合理使用分页参数,避免一次性加载过多数据。
|
||||
- 批量创建时使用 URLSearchParams,确保后端高效处理。
|
||||
- 资源加载
|
||||
- 图标与组件按需使用,避免不必要的全局注册导致体积增大。
|
||||
|
||||
## 故障排查指南
|
||||
- 登录失败
|
||||
- 检查用户 Store 的登录接口是否正确返回 token;确认本地存储是否写入。
|
||||
- 路由守卫是否正确拦截未登录访问。
|
||||
- 菜单加载失败
|
||||
- 确认后端菜单树接口返回结构;组件中是否有默认回退逻辑。
|
||||
- 表单校验不生效
|
||||
- 确认 el-form 的 ref 与 validate 调用时机;rules 是否正确绑定。
|
||||
- 401 自动登出
|
||||
- 检查响应拦截器是否正确识别 401 并清除 token 与跳转登录。
|
||||
- 批量创建失败
|
||||
- 确认 URLSearchParams 的重复参数构造是否符合后端期望。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L11-L20)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L104-L113)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L101-L116)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L38-L63)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L40-L49)
|
||||
|
||||
## 结论
|
||||
本项目以 Vue 3 Composition API 为核心,结合 Pinia、Element Plus 与 axios 封装,形成了清晰的页面组件、状态管理与 API 层分工。通过统一的错误处理与路由守卫,提升了系统的稳定性与可用性。建议在后续迭代中进一步抽取可复用组件与工具函数,完善单元测试与端到端测试,持续优化性能与可维护性。
|
||||
|
||||
## 附录
|
||||
- 命名规范建议
|
||||
- 组件文件:PascalCase(如 Departments.vue)。
|
||||
- Store:useXxxStore(如 useUserStore)。
|
||||
- API 函数:动词+名词(如 getAssessments、createDepartment)。
|
||||
- 常量:UPPER_SNAKE_CASE(如 STATUS_MAP)。
|
||||
- 代码组织建议
|
||||
- 按功能域划分 views、stores、api,避免交叉耦合。
|
||||
- 将样式与主题变量集中在 assets/main.scss,统一风格。
|
||||
- 测试与调试
|
||||
- 使用 Vitest/Jest 编写组件与工具函数测试;利用浏览器 DevTools 与 Vue DevTools 调试响应式数据与生命周期。
|
||||
238
.qoder/repowiki/zh/content/前端开发指南/Vue组件开发/组件测试与调试.md
Normal file
238
.qoder/repowiki/zh/content/前端开发指南/Vue组件开发/组件测试与调试.md
Normal file
@@ -0,0 +1,238 @@
|
||||
# 组件测试与调试
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [package.json](file://frontend/package.json)
|
||||
- [vite.config.js](file://frontend/vite.config.js)
|
||||
- [main.js](file://frontend/src/main.js)
|
||||
- [App.vue](file://frontend/src/App.vue)
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md)
|
||||
- [frontend.md](file://docs/frontend.md)
|
||||
- [test_api.py](file://backend/test_api.py)
|
||||
- [test-api.html](file://frontend/public/test-api.html)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本指南面向Vue 3前端团队,围绕组件测试与调试提供系统化实践建议。结合当前仓库的前端工程配置与后端API,重点覆盖以下主题:
|
||||
- Vue Test Utils的安装与基础配置
|
||||
- 单元测试:渲染、交互、生命周期、异步
|
||||
- 集成测试策略:API集成、端到端联动
|
||||
- 组件Mock、依赖注入与测试数据准备
|
||||
- 调试工具:Vue DevTools、浏览器开发者工具、性能分析
|
||||
- 常见问题排查:渲染、状态更新、内存泄漏
|
||||
- 测试覆盖率与CI配置建议
|
||||
|
||||
## 项目结构
|
||||
前端采用Vite + Vue 3 + Pinia + Element Plus的现代化栈;后端提供REST API,前端通过Vite代理访问。整体结构清晰,便于进行组件级与端到端测试。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
FE["前端应用<br/>Vite + Vue 3 + Pinia + Element Plus"]
|
||||
BE["后端API<br/>FastAPI 应用"]
|
||||
Proxy["Vite 代理<br/>/api -> http://localhost:8000"]
|
||||
FE --> Proxy
|
||||
Proxy --> BE
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L21)
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L105-L107)
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L1-L27)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L21)
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [App.vue](file://frontend/src/App.vue#L1-L17)
|
||||
|
||||
## 核心组件
|
||||
- 应用入口与插件注册:在入口文件中完成Pinia、路由、Element Plus等初始化,确保测试环境与生产一致。
|
||||
- 组件规范:推荐使用<script setup>组合式语法,统一命名规范,便于测试时稳定选择器与断言。
|
||||
- API层封装:基于Axios的请求实例与拦截器,统一处理鉴权与错误提示,利于在测试中注入或替换。
|
||||
|
||||
章节来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [frontend.md](file://docs/frontend.md#L50-L131)
|
||||
|
||||
## 架构总览
|
||||
下图展示前端组件与后端API的交互关系,以及测试阶段的关键接入点(代理、拦截器、Store)。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "前端"
|
||||
C1["组件"]
|
||||
S1["Pinia Store"]
|
||||
R1["路由"]
|
||||
AX["Axios 实例<br/>拦截器"]
|
||||
end
|
||||
subgraph "网络"
|
||||
P["Vite 代理<br/>/api -> 后端"]
|
||||
end
|
||||
subgraph "后端"
|
||||
API["FastAPI 路由"]
|
||||
end
|
||||
C1 --> AX
|
||||
AX --> P
|
||||
P --> API
|
||||
C1 --> S1
|
||||
C1 --> R1
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L12-L20)
|
||||
- [frontend.md](file://docs/frontend.md#L92-L131)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 安装与基础配置(Vue Test Utils)
|
||||
- 安装依赖:添加测试框架与适配器(如@vue/test-utils、vitest),并配置别名与代理以复用生产环境网络行为。
|
||||
- 全局插件:在测试入口注册Pinia、路由、Element Plus,保证组件挂载与渲染一致性。
|
||||
- 代理与拦截器:保留Vite代理与Axios拦截器,便于对真实网络请求进行Mock或替换。
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L21-L25)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L7-L11)
|
||||
- [main.js](file://frontend/src/main.js#L19-L21)
|
||||
|
||||
### 渲染测试
|
||||
- 目标:验证组件在不同props与状态下的渲染结果,确保DOM结构与文本内容符合预期。
|
||||
- 关键点:使用全局插件快照渲染,避免遗漏Element Plus样式与国际化配置;针对Element Plus组件使用其提供的测试工具或模拟实现。
|
||||
- 断言建议:优先基于可测试性属性(如data-testid)定位元素,减少对内部实现细节的耦合。
|
||||
|
||||
章节来源
|
||||
- [frontend.md](file://docs/frontend.md#L50-L91)
|
||||
|
||||
### 交互测试
|
||||
- 目标:验证用户交互(点击、输入、切换)触发的状态变化与副作用。
|
||||
- 关键点:使用事件触发器模拟用户操作;对于Element Plus组件,优先使用其官方提供的测试工具或模拟组件。
|
||||
- 注意:在测试中保持与生产一致的拦截器行为,必要时对Axios实例进行Mock以隔离外部依赖。
|
||||
|
||||
章节来源
|
||||
- [frontend.md](file://docs/frontend.md#L92-L131)
|
||||
|
||||
### 生命周期测试
|
||||
- 目标:验证组件在挂载、卸载、更新过程中的副作用(如订阅、定时器、网络请求)。
|
||||
- 关键点:在测试中模拟或清理副作用;对异步副作用使用微任务或定时器工具推进执行。
|
||||
- 建议:对组合式函数中的副作用进行模块化拆分,便于独立测试与替换。
|
||||
|
||||
章节来源
|
||||
- [frontend.md](file://docs/frontend.md#L50-L84)
|
||||
|
||||
### 异步测试
|
||||
- 目标:验证异步数据加载、错误处理与Loading态。
|
||||
- 关键点:使用异步断言等待DOM更新;对Axios请求进行Mock,控制响应时间与状态码。
|
||||
- 建议:在测试中统一使用同一Axios实例,便于集中Mock与断言。
|
||||
|
||||
章节来源
|
||||
- [frontend.md](file://docs/frontend.md#L92-L131)
|
||||
|
||||
### 集成测试策略
|
||||
- API集成测试:通过Vite代理将测试请求转发至后端,使用Mock数据或真实数据库,验证端到端流程。
|
||||
- 端到端联动:在集成测试中同时启动前端与后端,使用真实用户场景驱动组件与API协作。
|
||||
- 依赖注入:在测试中注入替代服务或存储,隔离外部依赖,提升测试稳定性与速度。
|
||||
|
||||
章节来源
|
||||
- [vite.config.js](file://frontend/vite.config.js#L12-L20)
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L105-L107)
|
||||
|
||||
### 组件Mock技术、依赖注入与测试数据准备
|
||||
- 组件Mock:对第三方组件(如Element Plus)或复杂子组件进行浅层渲染或模拟实现,聚焦被测组件逻辑。
|
||||
- 依赖注入:通过全局插件或工厂函数注入替代服务(如API客户端、Store模块),便于在测试中控制输入与输出。
|
||||
- 测试数据:准备典型与边界数据集,覆盖正常、异常与空数据场景;对日期、金额等格式化字段进行一致性校验。
|
||||
|
||||
章节来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [frontend.md](file://docs/frontend.md#L92-L131)
|
||||
|
||||
### 调试工具使用
|
||||
- Vue DevTools:检查组件树、Props、状态与事件流,定位渲染与状态问题。
|
||||
- 浏览器开发者工具:利用Console与Network标签排查CORS、404、500与网络错误;结合后端日志定位问题根因。
|
||||
- 性能分析:使用Performance标签观察重排、重绘与长任务,识别渲染瓶颈。
|
||||
|
||||
章节来源
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L1-L119)
|
||||
|
||||
### 常见问题排查
|
||||
- 组件渲染问题:检查全局插件是否完整注册、Element Plus样式是否生效、别名解析是否正确。
|
||||
- 状态更新问题:确认响应式数据变更触发了重新渲染,避免直接修改对象引用;检查异步回调中的状态更新时机。
|
||||
- 内存泄漏检测:排查未清理的订阅、定时器与事件监听器;在组件卸载钩子中统一清理。
|
||||
|
||||
章节来源
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L10-L39)
|
||||
|
||||
### 测试覆盖率与持续集成配置
|
||||
- 覆盖率:在测试框架中启用覆盖率统计,关注组件、路由与API层的覆盖率阈值。
|
||||
- CI:在CI流水线中执行单元测试、集成测试与覆盖率检查,确保每次提交的质量门禁。
|
||||
|
||||
[本节为通用实践建议,不直接分析具体文件]
|
||||
|
||||
## 依赖分析
|
||||
前端依赖与配置对测试的影响:
|
||||
- Vite别名与代理:影响测试中资源解析与网络请求路径。
|
||||
- 插件生态:Element Plus、Pinia、Vue Router均需在测试环境中正确注册。
|
||||
- Axios拦截器:统一处理鉴权与错误,测试中可通过替换实例或拦截器实现可控行为。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
Vite["Vite 别名与代理"]
|
||||
Plugins["插件注册<br/>Pinia / Router / Element Plus"]
|
||||
Axios["Axios 拦截器"]
|
||||
Tests["测试套件"]
|
||||
Vite --> Tests
|
||||
Plugins --> Tests
|
||||
Axios --> Tests
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [vite.config.js](file://frontend/vite.config.js#L7-L11)
|
||||
- [main.js](file://frontend/src/main.js#L19-L21)
|
||||
- [frontend.md](file://docs/frontend.md#L92-L131)
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L11-L25)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L21)
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
|
||||
## 性能考虑
|
||||
- 渲染性能:减少不必要的响应式依赖与深层嵌套,使用计算属性与懒加载。
|
||||
- 网络性能:合并请求、缓存策略与防抖,避免频繁重渲染。
|
||||
- 测试性能:在测试中使用Mock与轻量数据,缩短执行时间。
|
||||
|
||||
[本节为通用指导,不直接分析具体文件]
|
||||
|
||||
## 故障排查指南
|
||||
- 控制台与网络:根据错误类型定位CORS、404、500与网络异常,结合后端日志与健康检查接口快速定位。
|
||||
- 接口测试工具:使用内置测试页面或脚本验证后端可用性与鉴权流程。
|
||||
- 缓存与重启:清理浏览器缓存与本地存储,必要时重启前后端服务。
|
||||
|
||||
章节来源
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L10-L95)
|
||||
- [test_api.py](file://backend/test_api.py#L1-L33)
|
||||
- [test-api.html](file://frontend/public/test-api.html)
|
||||
|
||||
## 结论
|
||||
通过统一的测试配置、规范化的组件与API层设计,以及完善的调试与排错流程,可以显著提升组件测试的可靠性与效率。建议在现有工程基础上逐步引入单元与集成测试,并在CI中强制覆盖率门槛,保障系统长期演进的稳定性。
|
||||
|
||||
[本节为总结性内容,不直接分析具体文件]
|
||||
|
||||
## 附录
|
||||
- 快速参考
|
||||
- 前端开发服务器:http://localhost:5173
|
||||
- 后端健康检查:http://localhost:8000/health
|
||||
- API文档:http://localhost:8000/api/v1/docs
|
||||
- 默认账号:admin / admin123
|
||||
|
||||
章节来源
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L97-L119)
|
||||
412
.qoder/repowiki/zh/content/前端开发指南/Vue组件开发/组件设计模式.md
Normal file
412
.qoder/repowiki/zh/content/前端开发指南/Vue组件开发/组件设计模式.md
Normal file
@@ -0,0 +1,412 @@
|
||||
# 组件设计模式
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [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)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [组件详解](#组件详解)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 引言
|
||||
本指南围绕 Vue 组件设计模式,结合仓库中的前端实现,系统阐述组件拆分原则、单一职责与高内聚低耦合理念;容器组件与展示组件的分离;组件抽象与复用策略;组件通信(父子、兄弟、跨级、事件总线);状态管理(全局与局部);组件边界与接口设计;以及测试策略与 Mock 数据实践。目标是帮助读者在实际项目中构建清晰、可维护、可扩展的组件体系。
|
||||
|
||||
## 项目结构
|
||||
前端采用典型的单页应用结构:入口应用、路由、布局、业务视图、状态管理与 API 层。整体遵循“关注点分离”和“按功能域组织”的原则,便于团队协作与长期演进。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A["main.js<br/>应用入口"] --> B["App.vue<br/>根组件"]
|
||||
A --> C["router/index.js<br/>路由配置"]
|
||||
A --> D["stores/*<br/>Pinia 状态"]
|
||||
A --> E["api/*<br/>API 导出聚合"]
|
||||
B --> F["router-view<br/>动态渲染视图"]
|
||||
F --> G["Layout.vue<br/>布局容器"]
|
||||
G --> H["views/*<br/>业务视图"]
|
||||
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["后端服务<br/>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<bool>
|
||||
+getUserInfo() Promise<object>
|
||||
+logout() void
|
||||
}
|
||||
class AppStore {
|
||||
+boolean collapsed
|
||||
+array departmentTree
|
||||
+toggleSidebar() void
|
||||
+loadDepartmentTree() Promise<void>
|
||||
}
|
||||
class StoresIndex {
|
||||
+useUserStore()
|
||||
+useAppStore()
|
||||
}
|
||||
StoresIndex --> UserStore : "导出"
|
||||
StoresIndex --> AppStore : "导出"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [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/stores/index.js](file://frontend/src/stores/index.js#L1-L3)
|
||||
|
||||
章节来源
|
||||
- [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/stores/index.js](file://frontend/src/stores/index.js#L1-L3)
|
||||
|
||||
### API 聚合与请求
|
||||
- API 聚合
|
||||
- 在 api/index.js 中统一导出各模块 API,便于视图组件按需引入。
|
||||
- 请求配置
|
||||
- Vite 开发服务器配置了 /api 代理到后端服务地址,便于前后端联调。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L14-L19)
|
||||
|
||||
## 依赖关系分析
|
||||
- 组件依赖
|
||||
- 视图组件依赖路由、状态与 API;布局组件依赖菜单 API 与用户/应用 Store。
|
||||
- 状态依赖
|
||||
- 用户 Store 与路由守卫配合实现鉴权;应用 Store 管理 UI 状态。
|
||||
- 外部依赖
|
||||
- Element Plus 提供图标、表单、表格、图表等 UI 能力;ECharts 用于可视化;Axios 用于网络请求。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
V_Login["Login.vue"] --> S_User["useUserStore"]
|
||||
V_Dash["Dashboard.vue"] --> API_Stats["stats API"]
|
||||
V_Dash --> ECharts["ECharts"]
|
||||
V_Dept["Departments.vue"] --> API_Dept["department API"]
|
||||
V_Asm["Assessments.vue"] --> API_Asm["assessment API"]
|
||||
V_AsmD["AssessmentDetail.vue"] --> API_Asm["assessment API"]
|
||||
Layout["Layout.vue"] --> S_App["useAppStore"]
|
||||
Layout --> API_Menu["menu API"]
|
||||
Main["main.js"] --> Router["router/index.js"]
|
||||
Main --> Stores["stores/*"]
|
||||
Main --> App["App.vue"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L55-L89)
|
||||
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L229-L231)
|
||||
- [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L106-L106)
|
||||
- [frontend/src/views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L120-L122)
|
||||
- [frontend/src/views/assessment/AssessmentDetail.vue](file://frontend/src/views/assessment/AssessmentDetail.vue#L102-L102)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L77-L81)
|
||||
- [frontend/src/main.js](file://frontend/src/main.js#L1-L24)
|
||||
|
||||
章节来源
|
||||
- [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)
|
||||
|
||||
## 性能考量
|
||||
- 路由懒加载
|
||||
- 路由组件使用动态导入,减少首屏体积,提升初始加载速度。
|
||||
- 图表性能
|
||||
- 仅在需要时初始化图表实例;监听窗口 resize 事件进行自适应;避免重复 setOption。
|
||||
- 状态缓存
|
||||
- 对于不频繁变化的数据(如菜单树、科室树)进行本地缓存,减少重复请求。
|
||||
- 交互反馈
|
||||
- 使用加载状态与防抖,避免频繁触发请求;对大列表使用分页与虚拟滚动(如后续扩展)。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L4-L96)
|
||||
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L441-L448)
|
||||
|
||||
## 故障排查指南
|
||||
- 登录失败
|
||||
- 检查用户 Store 的登录返回值与错误处理;确认路由守卫是否正确拦截未登录访问。
|
||||
- 菜单加载失败
|
||||
- 检查菜单 API 返回结构与转换逻辑;确保降级菜单可用。
|
||||
- 图表空白或不更新
|
||||
- 检查图表实例是否初始化;确认数据源是否存在;验证 resize 事件绑定。
|
||||
- 鉴权失效
|
||||
- 检查本地 Token 是否存在;确认登出时是否清除 Token 并跳转登录。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L73-L89)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L86-L116)
|
||||
- [frontend/src/views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L441-L448)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L34-L39)
|
||||
|
||||
## 结论
|
||||
本项目在组件设计上体现了清晰的分层与职责划分:布局容器负责页面骨架与状态,业务视图承担数据与交互,Pinia 管理共享状态,API 聚合提供稳定接口。通过路由懒加载、图表性能优化与状态缓存等手段,兼顾了可维护性与用户体验。建议在后续迭代中进一步完善单元测试与集成测试,强化组件边界与接口契约,持续提升系统的稳定性与可扩展性。
|
||||
|
||||
## 附录
|
||||
- 组件拆分原则
|
||||
- 单一职责:每个组件只负责一个功能域内的展示与交互。
|
||||
- 高内聚:组件内部逻辑紧密相关,减少外部依赖。
|
||||
- 低耦合:通过明确的 props 与事件进行通信,避免直接依赖 DOM 或全局变量。
|
||||
- 容器与展示组件
|
||||
- 容器组件:负责数据加载、状态管理与流程控制;展示组件:负责具体 UI 渲染与用户交互。
|
||||
- 组件抽象与复用
|
||||
- 将通用逻辑(如表单校验、状态映射、图表配置)抽离为可复用函数或组合式工具。
|
||||
- 组件通信
|
||||
- 父子通信:通过 props 下传与 emits 上抛;兄弟通信:通过共同父组件或事件总线;跨级通信:通过事件总线或全局状态;事件总线:谨慎使用,建议优先选择 Pinia。
|
||||
- 状态管理
|
||||
- 局部状态:组件内部使用 ref/reactive;全局状态:Pinia Store;持久化:Token 存储于 localStorage。
|
||||
- 接口与边界
|
||||
- 明确输入输出类型;对异常情况进行降级处理;对外暴露稳定的 API 接口。
|
||||
- 测试策略
|
||||
- 单元测试:针对纯函数与组合式逻辑;集成测试:针对组件生命周期与交互流程;Mock 数据:使用静态 JSON 或模拟 API 返回。
|
||||
Reference in New Issue
Block a user