提交文件
This commit is contained in:
397
.qoder/repowiki/zh/content/前端开发指南/API集成与数据处理.md
Normal file
397
.qoder/repowiki/zh/content/前端开发指南/API集成与数据处理.md
Normal file
@@ -0,0 +1,397 @@
|
||||
# API集成与数据处理
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js)
|
||||
- [frontend/src/api/index.js](file://frontend/src/api/index.js)
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js)
|
||||
- [frontend/src/api/staff.js](file://frontend/src/api/staff.js)
|
||||
- [frontend/src/api/indicator.js](file://frontend/src/api/indicator.js)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js)
|
||||
- [frontend/src/api/salary.js](file://frontend/src/api/salary.js)
|
||||
- [frontend/src/api/template.js](file://frontend/src/api/template.js)
|
||||
- [frontend/src/api/stats.js](file://frontend/src/api/stats.js)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js)
|
||||
- [frontend/package.json](file://frontend/package.json)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本指南围绕前端API集成与数据处理展开,覆盖HTTP请求封装、拦截器配置与错误处理、认证token管理、请求参数与查询条件传递、响应数据处理与状态码判断、分页与筛选排序、以及开发环境代理与生产部署要点。文档同时给出常见问题排查建议,帮助开发者快速理解并扩展该系统的API层。
|
||||
|
||||
## 项目结构
|
||||
前端采用模块化API目录组织,按业务域拆分接口文件,并通过统一的请求封装与拦截器实现跨域代理、鉴权、错误提示等横切能力;Pinia用于状态管理,Vue Router负责路由与鉴权守卫;Vite提供开发服务器与代理配置。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "前端"
|
||||
VUE["Vue 应用<br/>main.js"]
|
||||
ROUTER["路由<br/>router/index.js"]
|
||||
STORE_USER["用户状态<br/>stores/user.js"]
|
||||
STORE_APP["应用状态<br/>stores/app.js"]
|
||||
API_INDEX["API聚合<br/>api/index.js"]
|
||||
API_REQ["请求封装<br/>api/request.js"]
|
||||
API_AUTH["认证接口<br/>api/auth.js"]
|
||||
API_DEPT["科室接口<br/>api/department.js"]
|
||||
API_STAFF["员工接口<br/>api/staff.js"]
|
||||
API_IND["指标接口<br/>api/indicator.js"]
|
||||
API_ASSESS["考核接口<br/>api/assessment.js"]
|
||||
API_SAL["工资接口<br/>api/salary.js"]
|
||||
API_TPL["模板接口<br/>api/template.js"]
|
||||
API_STATS["统计接口<br/>api/stats.js"]
|
||||
end
|
||||
VUE --> ROUTER
|
||||
VUE --> STORE_USER
|
||||
VUE --> STORE_APP
|
||||
VUE --> API_INDEX
|
||||
API_INDEX --> API_REQ
|
||||
API_INDEX --> API_AUTH
|
||||
API_INDEX --> API_DEPT
|
||||
API_INDEX --> API_STAFF
|
||||
API_INDEX --> API_IND
|
||||
API_INDEX --> API_ASSESS
|
||||
API_INDEX --> API_SAL
|
||||
API_INDEX --> API_TPL
|
||||
API_INDEX --> API_STATS
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [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)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
- [frontend/src/api/staff.js](file://frontend/src/api/staff.js#L1-L32)
|
||||
- [frontend/src/api/indicator.js](file://frontend/src/api/indicator.js#L1-L32)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L1-L50)
|
||||
- [frontend/src/api/salary.js](file://frontend/src/api/salary.js#L1-L42)
|
||||
- [frontend/src/api/template.js](file://frontend/src/api/template.js#L1-L62)
|
||||
- [frontend/src/api/stats.js](file://frontend/src/api/stats.js#L1-L43)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [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)
|
||||
|
||||
## 核心组件
|
||||
- 统一请求封装与拦截器
|
||||
- 基础配置:基础URL、超时、默认Content-Type
|
||||
- 请求拦截:自动注入Authorization头(Bearer Token)
|
||||
- 响应拦截:统一错误码判断、状态码分支处理、消息提示与路由跳转
|
||||
- 认证与会话管理
|
||||
- 登录、获取当前用户、登出
|
||||
- Token持久化与路由守卫联动
|
||||
- 状态管理
|
||||
- 用户状态:token、userInfo、登录/登出
|
||||
- 应用状态:侧边栏折叠、科室树加载
|
||||
- 路由与鉴权
|
||||
- 全局前置守卫:未登录禁止访问受保护页面
|
||||
- 开发代理与构建
|
||||
- Vite代理到后端服务
|
||||
- 构建脚本与依赖
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L12-L20)
|
||||
- [frontend/package.json](file://frontend/package.json#L6-L10)
|
||||
|
||||
## 架构总览
|
||||
下图展示从前端调用到后端服务的整体链路,包括请求拦截、认证、响应处理与错误反馈。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant View as "视图组件"
|
||||
participant Store as "Pinia状态"
|
||||
participant API as "API模块"
|
||||
participant Req as "请求封装(request.js)"
|
||||
participant Axios as "Axios实例"
|
||||
participant Proxy as "Vite代理(/api)"
|
||||
participant Backend as "后端服务"
|
||||
View->>Store : 触发动作(如登录/加载数据)
|
||||
Store->>API : 调用具体接口函数
|
||||
API->>Req : 发起HTTP请求
|
||||
Req->>Axios : 配置headers/params/timeout
|
||||
Axios->>Proxy : 将/api前缀转发
|
||||
Proxy->>Backend : 代理到后端地址
|
||||
Backend-->>Proxy : 返回JSON响应
|
||||
Proxy-->>Axios : 返回响应
|
||||
Axios-->>Req : 进入响应拦截器
|
||||
Req-->>API : 统一处理code/status
|
||||
API-->>Store : 返回标准化数据
|
||||
Store-->>View : 更新UI
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L6-L12)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L14-L26)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L28-L63)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L14-L19)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 统一请求封装与拦截器
|
||||
- 基础配置
|
||||
- 基础URL为/api/v1,所有接口以此为前缀
|
||||
- 默认超时30秒,Content-Type为application/json
|
||||
- 请求拦截器
|
||||
- 从localStorage读取token并在请求头Authorization中附加Bearer前缀
|
||||
- 响应拦截器
|
||||
- 自定义code字段判断:当code不等于200时,弹出错误消息并reject
|
||||
- 对常见HTTP状态码进行分支处理:401清理token并跳转登录、403无权限、404资源不存在、500服务器错误
|
||||
- 其他错误:优先展示后端detail,否则提示网络错误
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["进入响应拦截器"]) --> CheckCode["检查自定义code字段"]
|
||||
CheckCode --> CodeOK{"code是否为200?"}
|
||||
CodeOK --> |是| ReturnRes["返回data"]
|
||||
CodeOK --> |否| ShowMsg["弹出错误消息"]
|
||||
ShowMsg --> RejectErr["Promise.reject(error)"]
|
||||
ReturnRes --> End(["结束"])
|
||||
RejectErr --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L28-L37)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L6-L12)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L14-L26)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L28-L63)
|
||||
|
||||
### 认证与会话管理
|
||||
- 登录
|
||||
- 使用表单编码提交用户名与密码
|
||||
- 成功后保存access_token至localStorage并写入store
|
||||
- 获取当前用户
|
||||
- 通过受保护接口获取用户信息
|
||||
- 登出
|
||||
- 清空token与用户信息,删除localStorage中的token并跳转登录页
|
||||
- 路由守卫
|
||||
- 未携带token访问受保护路由时重定向至登录页
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant View as "登录页"
|
||||
participant Store as "useUserStore"
|
||||
participant API as "auth.js"
|
||||
participant Req as "request.js"
|
||||
participant Router as "router/index.js"
|
||||
View->>Store : 调用login(username,password)
|
||||
Store->>API : 调用login接口
|
||||
API->>Req : POST /auth/login(表单编码)
|
||||
Req-->>API : 返回{access_token}
|
||||
API-->>Store : 返回token
|
||||
Store->>Store : 写入localStorage与store
|
||||
Store->>Router : 登录成功后继续导航
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L4-L11)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L11-L20)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
|
||||
### 数据格式与参数传递
|
||||
- 查询参数
|
||||
- 多数GET接口通过{ params }传入查询条件,支持分页、筛选、排序等
|
||||
- 特殊场景
|
||||
- 批量创建考核时,后端期望重复的查询参数名,前端使用URLSearchParams拼接数组值
|
||||
- 表单提交
|
||||
- 登录接口使用application/x-www-form-urlencoded,其余接口默认JSON
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L4-L5)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L40-L49)
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L5-L10)
|
||||
|
||||
### 响应数据处理与状态码判断
|
||||
- 自定义code字段
|
||||
- 当响应data.code不为200时,统一视为业务错误并提示
|
||||
- HTTP状态码分支
|
||||
- 401:清除token并跳转登录
|
||||
- 403/404/500:分别提示对应错误
|
||||
- 其他:展示后端detail或网络错误
|
||||
- 返回值
|
||||
- 成功时返回data,便于上层直接消费
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L28-L63)
|
||||
|
||||
### 分页、搜索与排序
|
||||
- 分页
|
||||
- 通过查询参数传递页码与每页数量,后端返回总数与列表
|
||||
- 搜索与过滤
|
||||
- 通过查询参数传入关键词与筛选条件
|
||||
- 排序
|
||||
- 通过查询参数传入排序字段与方向
|
||||
- 示例接口
|
||||
- 科室、员工、指标、模板、统计等均支持上述模式
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L4-L5)
|
||||
- [frontend/src/api/staff.js](file://frontend/src/api/staff.js#L4-L5)
|
||||
- [frontend/src/api/indicator.js](file://frontend/src/api/indicator.js#L4-L5)
|
||||
- [frontend/src/api/template.js](file://frontend/src/api/template.js#L4-L5)
|
||||
- [frontend/src/api/stats.js](file://frontend/src/api/stats.js#L4-L16)
|
||||
|
||||
### 文件上传与下载
|
||||
- 上传
|
||||
- 使用multipart/form-data提交文件,后端返回上传结果
|
||||
- 下载
|
||||
- 通过a链接或Blob对象触发浏览器下载
|
||||
- 进度显示
|
||||
- 可通过axios上传配置的onUploadProgress回调实现
|
||||
- 取消请求
|
||||
- 可使用AbortController在组件卸载或切换时取消未完成请求
|
||||
|
||||
说明:当前仓库未发现具体的上传/下载实现代码,以上为通用实践建议。
|
||||
|
||||
### Mock数据与开发环境
|
||||
- 开发代理
|
||||
- Vite将/api前缀代理到本地后端服务,避免跨域问题
|
||||
- Mock策略
|
||||
- 可在开发阶段引入mock库或后端模拟服务,便于联调与前端独立开发
|
||||
|
||||
章节来源
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L12-L20)
|
||||
|
||||
### 生产环境部署
|
||||
- 构建产物
|
||||
- 使用Vite构建静态资源,输出至dist目录
|
||||
- 静态部署
|
||||
- 将dist作为静态站点部署,保持/api前缀不变
|
||||
- 后端代理
|
||||
- 生产环境需确保/api请求能正确转发至后端服务
|
||||
|
||||
章节来源
|
||||
- [frontend/package.json](file://frontend/package.json#L6-L10)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L12-L20)
|
||||
|
||||
## 依赖关系分析
|
||||
- 组件耦合
|
||||
- API模块仅依赖统一请求封装,低耦合高内聚
|
||||
- 路由守卫与状态管理共同保障鉴权
|
||||
- 外部依赖
|
||||
- axios:HTTP客户端
|
||||
- element-plus:消息提示与UI组件
|
||||
- pinia/vue-router:状态与路由
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
API_REQ["api/request.js"] --> AXIOS["axios"]
|
||||
API_AUTH["api/auth.js"] --> API_REQ
|
||||
API_DEPT["api/department.js"] --> API_REQ
|
||||
API_STAFF["api/staff.js"] --> API_REQ
|
||||
API_IND["api/indicator.js"] --> API_REQ
|
||||
API_ASSESS["api/assessment.js"] --> API_REQ
|
||||
API_SAL["api/salary.js"] --> API_REQ
|
||||
API_TPL["api/template.js"] --> API_REQ
|
||||
API_STATS["api/stats.js"] --> API_REQ
|
||||
STORE_USER["stores/user.js"] --> API_AUTH
|
||||
STORE_APP["stores/app.js"] --> API_DEPT
|
||||
ROUTER["router/index.js"] --> STORE_USER
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
- [frontend/src/api/staff.js](file://frontend/src/api/staff.js#L1-L32)
|
||||
- [frontend/src/api/indicator.js](file://frontend/src/api/indicator.js#L1-L32)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L1-L50)
|
||||
- [frontend/src/api/salary.js](file://frontend/src/api/salary.js#L1-L42)
|
||||
- [frontend/src/api/template.js](file://frontend/src/api/template.js#L1-L62)
|
||||
- [frontend/src/api/stats.js](file://frontend/src/api/stats.js#L1-L43)
|
||||
- [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#L1-L116)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [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#L1-L116)
|
||||
|
||||
## 性能考虑
|
||||
- 请求合并与去抖
|
||||
- 对频繁触发的搜索/筛选操作,可在组件层增加防抖
|
||||
- 缓存策略
|
||||
- 对不常变动的数据(如字典、类型列表)可加入内存缓存
|
||||
- 分页与懒加载
|
||||
- 列表页使用分页,结合虚拟滚动提升渲染性能
|
||||
- 体积优化
|
||||
- 按需引入Element Plus组件,减少打包体积
|
||||
|
||||
## 故障排查指南
|
||||
- 登录后仍被重定向至登录页
|
||||
- 检查localStorage中token是否存在,确认路由守卫逻辑
|
||||
- 401错误频繁出现
|
||||
- 检查请求头Authorization是否正确附加,确认后端token有效期
|
||||
- 403/404/500错误
|
||||
- 查看后端日志与接口文档,确认权限与资源存在性
|
||||
- 网络错误提示
|
||||
- 检查Vite代理配置与后端服务连通性
|
||||
- 批量参数传递异常
|
||||
- 确认后端期望的重复参数名与数值类型
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L38-L61)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L14-L19)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L40-L49)
|
||||
|
||||
## 结论
|
||||
该前端API层通过统一的请求封装与拦截器实现了鉴权、错误处理与跨域代理,配合Pinia与路由守卫形成清晰的认证与状态管理闭环。业务接口按模块化组织,查询参数传递规范,具备良好的扩展性。建议在后续迭代中补充文件上传/下载与Mock能力,并完善批量参数与分页的通用工具方法,以进一步提升开发效率与用户体验。
|
||||
|
||||
## 附录
|
||||
- 常用接口一览(示例)
|
||||
- 认证:登录、获取当前用户、注册
|
||||
- 基础数据:科室、员工、指标、模板
|
||||
- 考核与工资:创建、提交、审核、生成、确认
|
||||
- 统计:部门统计、周期统计、趋势、排名、仪表盘、预警
|
||||
- 开发与部署
|
||||
- 开发:npm run dev(Vite启动+代理)
|
||||
- 构建:npm run build(输出dist)
|
||||
- 预览:npm run preview
|
||||
|
||||
章节来源
|
||||
- [frontend/src/api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
- [frontend/src/api/staff.js](file://frontend/src/api/staff.js#L1-L32)
|
||||
- [frontend/src/api/indicator.js](file://frontend/src/api/indicator.js#L1-L32)
|
||||
- [frontend/src/api/template.js](file://frontend/src/api/template.js#L1-L62)
|
||||
- [frontend/src/api/assessment.js](file://frontend/src/api/assessment.js#L1-L50)
|
||||
- [frontend/src/api/salary.js](file://frontend/src/api/salary.js#L1-L42)
|
||||
- [frontend/src/api/stats.js](file://frontend/src/api/stats.js#L1-L43)
|
||||
- [frontend/package.json](file://frontend/package.json#L6-L10)
|
||||
- [frontend/vite.config.js](file://frontend/vite.config.js#L12-L20)
|
||||
312
.qoder/repowiki/zh/content/前端开发指南/UI设计系统.md
Normal file
312
.qoder/repowiki/zh/content/前端开发指南/UI设计系统.md
Normal file
@@ -0,0 +1,312 @@
|
||||
# UI设计系统
|
||||
|
||||
<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)
|
||||
- [main.scss](file://frontend/src/assets/main.scss)
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue)
|
||||
- [Dashboard.vue](file://frontend/src/views/Dashboard.vue)
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue)
|
||||
- [Assessments.vue](file://frontend/src/views/assessment/Assessments.vue)
|
||||
- [index.js](file://frontend/src/router/index.js)
|
||||
- [app.js](file://frontend/src/stores/app.js)
|
||||
- [user.js](file://frontend/src/stores/user.js)
|
||||
- [auth.js](file://frontend/src/api/auth.js)
|
||||
- [request.js](file://frontend/src/api/request.js)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本指南面向Element Plus UI设计系统的使用与落地实践,结合仓库中的前端工程,系统讲解安装配置、主题定制、本地化设置、常用组件用法、布局与表单、数据展示与反馈、SCSS变量定制、主题切换与响应式设计、图标与动画、交互规范以及样式覆盖与品牌化定制等。文档以“循序渐进”的方式组织,既适合初学者快速上手,也便于资深开发者深入理解系统架构与最佳实践。
|
||||
|
||||
## 项目结构
|
||||
前端采用Vite + Vue 3 + Element Plus + Pinia + Vue Router的技术栈,Element Plus作为主要UI组件库,全局引入并配置中文本地化;通过SCSS进行主题变量与通用样式管理;路由负责页面导航与权限守卫;Pinia用于状态管理;Axios封装统一请求与错误处理。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A["入口应用<br/>main.js"] --> B["Element Plus 插件<br/>main.js"]
|
||||
A --> C["路由注册<br/>index.js"]
|
||||
A --> D["状态管理<br/>app.js / user.js"]
|
||||
A --> E["全局样式<br/>main.scss"]
|
||||
B --> F["组件库样式<br/>element-plus/dist/index.css"]
|
||||
B --> G["中文本地化<br/>zh-cn.mjs"]
|
||||
A --> H["图标注册<br/>@element-plus/icons-vue"]
|
||||
A --> I["视图组件<br/>Layout.vue / Dashboard.vue 等"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [main.scss](file://frontend/src/assets/main.scss#L1-L186)
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L1-L27)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [main.scss](file://frontend/src/assets/main.scss#L1-L186)
|
||||
|
||||
## 核心组件
|
||||
- Element Plus插件与本地化:在应用入口集中注册Element Plus并设置中文语言包,确保全局组件文案与交互符合中文习惯。
|
||||
- 图标系统:通过批量注册Element Plus图标组件,使图标可在模板中直接使用。
|
||||
- 路由与权限:路由守卫根据Token判断是否放行,未登录自动跳转至登录页。
|
||||
- 状态管理:Pinia Store负责侧边栏折叠状态、用户登录态与Token持久化。
|
||||
- 全局样式:SCSS变量统一管理主色、语义色、文本与边框等,页面卡片、表格、搜索栏等通用样式集中维护。
|
||||
|
||||
章节来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [App.vue](file://frontend/src/App.vue#L1-L17)
|
||||
- [index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [main.scss](file://frontend/src/assets/main.scss#L14-L81)
|
||||
|
||||
## 架构总览
|
||||
下图展示了从应用启动到页面渲染的关键流程,涵盖插件初始化、路由守卫、状态管理与组件渲染。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant M as "main.js"
|
||||
participant EP as "ElementPlus 插件"
|
||||
participant R as "路由守卫"
|
||||
participant V as "视图组件"
|
||||
participant S as "Pinia Store"
|
||||
U->>M : 启动应用
|
||||
M->>EP : 注册插件并设置中文本地化
|
||||
M->>R : 安装路由
|
||||
M->>S : 初始化 Pinia Store
|
||||
U->>R : 访问受保护页面
|
||||
R->>R : 校验 Token
|
||||
alt 未登录
|
||||
R-->>U : 重定向到登录页
|
||||
else 已登录
|
||||
R-->>V : 渲染目标视图
|
||||
end
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### Element Plus安装与配置
|
||||
- 依赖安装:通过包管理器安装Element Plus与图标库,并在开发依赖中引入Sass支持。
|
||||
- 插件注册:在应用入口引入Element Plus并设置中文本地化;同时批量注册图标组件,便于在模板中直接使用。
|
||||
- 全局样式:引入Element Plus内置样式,保证组件基础样式一致。
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L11-L25)
|
||||
- [main.js](file://frontend/src/main.js#L3-L21)
|
||||
|
||||
### 本地化设置
|
||||
- 应用级本地化:在根组件通过ConfigProvider包裹并设置语言包,确保整个应用的组件文案为中文。
|
||||
- 插件级本地化:在插件注册时传入语言配置,保证组件内部国际化生效。
|
||||
|
||||
章节来源
|
||||
- [App.vue](file://frontend/src/App.vue#L1-L9)
|
||||
- [main.js](file://frontend/src/main.js#L6)
|
||||
|
||||
### 布局组件
|
||||
- 侧边栏与头部:布局组件提供侧边菜单、面包屑、用户下拉等结构,支持侧边栏折叠与过渡动画。
|
||||
- 菜单与图标:菜单项支持动态加载与图标渲染,点击触发路由跳转。
|
||||
- 页面切换:使用过渡动画实现页面切换的淡入淡出效果。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["进入 Layout"]) --> LoadMenu["加载菜单树"]
|
||||
LoadMenu --> RenderHeader["渲染头部与面包屑"]
|
||||
RenderHeader --> ToggleSidebar{"点击折叠按钮?"}
|
||||
ToggleSidebar --> |是| Collapse["切换折叠状态"]
|
||||
ToggleSidebar --> |否| RenderMain["渲染主内容区"]
|
||||
Collapse --> RenderMain
|
||||
RenderMain --> Transition["页面切换过渡"]
|
||||
Transition --> End(["完成渲染"])
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue#L1-L125)
|
||||
|
||||
章节来源
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
|
||||
|
||||
### 表单组件
|
||||
- 搜索与筛选:使用输入框、选择器、日期选择器、树形选择器等组合形成搜索栏,配合分页组件实现数据筛选与翻页。
|
||||
- 表单校验:通过表单规则对必填字段进行校验,提交时显示加载状态。
|
||||
- 对话框与编辑:使用对话框承载新增/编辑表单,支持树形选择器、数字输入框、文本域等控件。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant V as "Departments.vue"
|
||||
participant API as "后端接口"
|
||||
participant EP as "ElementPlus 表单组件"
|
||||
U->>V : 输入搜索条件
|
||||
V->>EP : 校验表单规则
|
||||
EP-->>V : 校验结果
|
||||
U->>V : 点击查询/重置/新增
|
||||
V->>API : 发起请求
|
||||
API-->>V : 返回数据
|
||||
V->>EP : 渲染表格/分页/对话框
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L200)
|
||||
|
||||
章节来源
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L200)
|
||||
|
||||
### 数据展示组件
|
||||
- 表格:使用带条纹的表格展示数据,列头背景与文字颜色统一,支持状态标签、操作列等。
|
||||
- 分页:通过分页组件实现页码与每页数量切换,配合请求参数更新数据。
|
||||
- 状态标签与等级:根据状态或分数映射不同类型的标签与等级样式,提升可读性。
|
||||
|
||||
章节来源
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L17-L55)
|
||||
- [Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L31-L75)
|
||||
|
||||
### 反馈组件
|
||||
- 消息提示:统一通过消息提示组件展示成功/失败信息。
|
||||
- 确认对话框:使用确认对话框进行危险操作的二次确认。
|
||||
- 加载状态:表格与表单提交时使用加载状态,避免重复提交。
|
||||
|
||||
章节来源
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L105-L106)
|
||||
- [Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L119-L120)
|
||||
|
||||
### 图标使用
|
||||
- 图标注册:在应用入口批量注册图标组件,随后可在模板中以组件形式使用。
|
||||
- 图标渲染:在菜单、按钮、标签等位置按需渲染图标,增强视觉表达。
|
||||
|
||||
章节来源
|
||||
- [main.js](file://frontend/src/main.js#L14-L17)
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue#L10-L24)
|
||||
|
||||
### 动画与交互
|
||||
- 折叠过渡:侧边栏宽度变化使用CSS过渡,提供平滑的折叠/展开体验。
|
||||
- 页面切换:使用过渡动画实现页面切换的淡入淡出。
|
||||
- 下拉菜单:用户信息下拉菜单支持点击展开与收起。
|
||||
|
||||
章节来源
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue#L37-L38)
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue#L231-L239)
|
||||
|
||||
### 组件样式覆盖与品牌化定制
|
||||
- SCSS变量:通过CSS变量统一管理主色、语义色、文本与背景色,便于整体风格调整。
|
||||
- 页面卡片与表格:为页面卡片与表格提供统一的圆角、阴影与列头样式,提升一致性。
|
||||
- 状态标签与等级:为不同状态与分数区间提供统一的标签样式,便于识别与品牌化。
|
||||
|
||||
章节来源
|
||||
- [main.scss](file://frontend/src/assets/main.scss#L14-L81)
|
||||
- [main.scss](file://frontend/src/assets/main.scss#L126-L179)
|
||||
|
||||
### 主题定制与切换
|
||||
- 当前状态:项目已通过插件注册设置中文本地化,但未实现主题切换功能。
|
||||
- 实现建议:可通过Element Plus的主题变量覆盖或CSS变量切换实现主题切换;在应用入口或路由守卫中根据用户偏好或系统主题进行切换。
|
||||
|
||||
章节来源
|
||||
- [main.js](file://frontend/src/main.js#L6)
|
||||
- [App.vue](file://frontend/src/App.vue#L1-L9)
|
||||
|
||||
### 响应式设计
|
||||
- 视口与容器:页面容器高度为视口高度,确保在不同屏幕尺寸下的适配。
|
||||
- 表格与卡片:卡片与表格在小屏设备上保持良好的可读性与间距。
|
||||
- 建议:可结合媒体查询或Element Plus栅格系统进一步优化移动端体验。
|
||||
|
||||
章节来源
|
||||
- [main.scss](file://frontend/src/assets/main.scss#L29-L61)
|
||||
|
||||
## 依赖关系分析
|
||||
- Element Plus:作为UI组件库,被应用入口注册并贯穿于所有视图组件。
|
||||
- 路由与状态:路由负责页面导航与权限控制,Pinia负责状态共享与持久化。
|
||||
- 请求封装:Axios封装统一请求与错误处理,结合Element Plus的消息提示提升用户体验。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
EP["ElementPlus"] --> Views["视图组件"]
|
||||
Router["路由"] --> Views
|
||||
Store["Pinia Store"] --> Views
|
||||
Axios["Axios 封装"] --> API["后端接口"]
|
||||
Views --> API
|
||||
API --> Axios
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
|
||||
章节来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
|
||||
## 性能考虑
|
||||
- 组件懒加载:路由采用异步组件加载,减少首屏体积。
|
||||
- 图标按需:仅注册所需图标,避免引入过多图标资源。
|
||||
- 请求拦截:统一处理错误与超时,减少无效请求造成的性能损耗。
|
||||
- 样式复用:通过SCSS变量与通用类名减少重复样式,降低CSS体积。
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L6-L10)
|
||||
- [main.js](file://frontend/src/main.js#L14-L17)
|
||||
- [request.js](file://frontend/src/api/request.js#L14-L63)
|
||||
|
||||
## 故障排查指南
|
||||
- 登录态失效:当后端返回401时,自动清除Token并跳转登录页,同时通过消息提示告知用户。
|
||||
- 权限不足:403错误提示无权限访问。
|
||||
- 资源不存在:404错误提示资源不存在。
|
||||
- 服务器异常:500错误提示服务器错误。
|
||||
- 网络异常:断网或请求超时提示网络错误。
|
||||
|
||||
章节来源
|
||||
- [request.js](file://frontend/src/api/request.js#L28-L63)
|
||||
- [index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [user.js](file://frontend/src/stores/user.js#L33-L39)
|
||||
|
||||
## 结论
|
||||
本项目以Element Plus为核心,结合Vue生态实现了完整的前端界面与交互体系。通过统一的本地化、图标与样式管理,以及完善的路由与状态管理,形成了清晰的UI设计系统。后续可在现有基础上扩展主题切换、移动端优化与更丰富的交互动效,持续提升用户体验与品牌一致性。
|
||||
|
||||
## 附录
|
||||
|
||||
### 常用组件使用清单
|
||||
- 布局:菜单、面包屑、头像、下拉菜单、折叠按钮
|
||||
- 表单:输入框、选择器、日期选择器、树形选择器、数字输入框、文本域、表单校验
|
||||
- 数据展示:表格、分页、标签、等级标签
|
||||
- 反馈:消息提示、确认对话框、加载状态
|
||||
|
||||
章节来源
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue#L10-L68)
|
||||
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L3-L100)
|
||||
- [Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L114)
|
||||
|
||||
### API与状态管理
|
||||
- 登录与用户信息:通过封装的请求模块调用后端接口,结合Pinia Store管理Token与用户信息。
|
||||
- 路由守卫:根据Token决定页面访问权限,未登录自动跳转登录页。
|
||||
|
||||
章节来源
|
||||
- [auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
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 返回。
|
||||
437
.qoder/repowiki/zh/content/前端开发指南/前端开发指南.md
Normal file
437
.qoder/repowiki/zh/content/前端开发指南/前端开发指南.md
Normal file
@@ -0,0 +1,437 @@
|
||||
# 前端开发指南
|
||||
|
||||
<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)
|
||||
- [router/index.js](file://frontend/src/router/index.js)
|
||||
- [stores/index.js](file://frontend/src/stores/index.js)
|
||||
- [stores/user.js](file://frontend/src/stores/user.js)
|
||||
- [stores/app.js](file://frontend/src/stores/app.js)
|
||||
- [views/Layout.vue](file://frontend/src/views/Layout.vue)
|
||||
- [views/Login.vue](file://frontend/src/views/Login.vue)
|
||||
- [views/Dashboard.vue](file://frontend/src/views/Dashboard.vue)
|
||||
- [views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue)
|
||||
- [views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue)
|
||||
- [views/reports/Reports.vue](file://frontend/src/views/reports/Reports.vue)
|
||||
- [api/request.js](file://frontend/src/api/request.js)
|
||||
- [api/auth.js](file://frontend/src/api/auth.js)
|
||||
- [api/index.js](file://frontend/src/api/index.js)
|
||||
- [assets/main.scss](file://frontend/src/assets/main.scss)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本指南面向医院绩效系统的前端开发团队,围绕 Vue 3 Composition API 的使用、组件架构设计与状态管理策略展开,同时覆盖路由配置、API 调用封装、UI 组件设计规范、Element Plus 组件库使用、样式定制与响应式布局、组件开发最佳实践、代码组织结构、构建与部署流程,以及开发环境配置、热重载与生产构建优化、常见问题与性能优化建议。
|
||||
|
||||
## 项目结构
|
||||
前端采用 Vite + Vue 3 + Pinia + Element Plus 技术栈,目录组织遵循按功能域划分的模块化思路:
|
||||
- 根级配置:package.json、vite.config.js
|
||||
- 应用入口:main.js、App.vue
|
||||
- 路由:src/router/index.js
|
||||
- 状态管理:src/stores 下的用户与应用状态
|
||||
- 视图层:src/views 下按业务域划分的页面组件
|
||||
- API 层:src/api 下按领域划分的接口模块与统一请求封装
|
||||
- 样式:src/assets/main.scss 提供全局样式与主题变量
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A["main.js<br/>应用入口"] --> B["App.vue<br/>根组件"]
|
||||
A --> C["router/index.js<br/>路由配置"]
|
||||
A --> D["stores/*<br/>Pinia 状态"]
|
||||
B --> E["views/Layout.vue<br/>布局容器"]
|
||||
E --> F["views/Login.vue<br/>登录页"]
|
||||
E --> G["views/Dashboard.vue<br/>工作台"]
|
||||
E --> H["views/basic/Departments.vue<br/>基础数据-科室"]
|
||||
E --> I["views/assessment/Assessments.vue<br/>考核管理"]
|
||||
E --> J["views/reports/Reports.vue<br/>统计报表"]
|
||||
A --> K["api/request.js<br/>HTTP 封装"]
|
||||
K --> L["api/auth.js<br/>认证接口"]
|
||||
K --> M["api/index.js<br/>接口聚合导出"]
|
||||
A --> N["assets/main.scss<br/>全局样式"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [App.vue](file://frontend/src/App.vue#L1-L17)
|
||||
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
|
||||
- [views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
|
||||
- [views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L1-L800)
|
||||
- [views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
|
||||
- [views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
|
||||
- [views/reports/Reports.vue](file://frontend/src/views/reports/Reports.vue#L1-L367)
|
||||
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
- [assets/main.scss](file://frontend/src/assets/main.scss#L1-L186)
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L1-L27)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [App.vue](file://frontend/src/App.vue#L1-L17)
|
||||
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [stores/index.js](file://frontend/src/stores/index.js#L1-L3)
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
|
||||
- [views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
|
||||
- [views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L1-L800)
|
||||
- [views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
|
||||
- [views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
|
||||
- [views/reports/Reports.vue](file://frontend/src/views/reports/Reports.vue#L1-L367)
|
||||
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
- [assets/main.scss](file://frontend/src/assets/main.scss#L1-L186)
|
||||
|
||||
## 核心组件
|
||||
- 应用入口与插件注册:在入口文件中完成 Element Plus 国际化、图标全局注册、Pinia、路由挂载与全局样式引入。
|
||||
- 根组件:通过 Config Provider 统一语言包,简化多组件国际化使用。
|
||||
- 路由系统:采用 History 模式,定义登录页与主框架嵌套路由,含面包屑标题与全局前置守卫。
|
||||
- 状态管理:使用 Pinia 定义用户与应用状态,支持登录态持久化、菜单树与侧边栏状态。
|
||||
- API 层:统一 Axios 实例,拦截器处理鉴权头、错误提示与路由跳转;接口模块按领域拆分并聚合导出。
|
||||
- 视图组件:采用 Composition API 编写,结合 Element Plus 组件实现表单、表格、对话框、图表等。
|
||||
|
||||
章节来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [App.vue](file://frontend/src/App.vue#L1-L17)
|
||||
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
|
||||
## 架构总览
|
||||
系统采用“视图层-状态层-接口层-基础设施层”的分层架构:
|
||||
- 视图层:页面组件负责交互与展示,使用 Composition API 管理本地状态与生命周期。
|
||||
- 状态层:Pinia Store 管理跨组件共享的状态与业务逻辑。
|
||||
- 接口层:Axios 封装统一处理请求/响应拦截,接口模块按领域拆分。
|
||||
- 基础设施:Vite 构建工具、Element Plus UI 库、SCSS 全局样式。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "视图层"
|
||||
V1["views/Login.vue"]
|
||||
V2["views/Layout.vue"]
|
||||
V3["views/Dashboard.vue"]
|
||||
V4["views/basic/Departments.vue"]
|
||||
V5["views/assessment/Assessments.vue"]
|
||||
V6["views/reports/Reports.vue"]
|
||||
end
|
||||
subgraph "状态层"
|
||||
S1["stores/user.js"]
|
||||
S2["stores/app.js"]
|
||||
end
|
||||
subgraph "接口层"
|
||||
I1["api/request.js"]
|
||||
I2["api/auth.js"]
|
||||
I3["api/index.js"]
|
||||
end
|
||||
subgraph "基础设施"
|
||||
B1["main.js"]
|
||||
B2["router/index.js"]
|
||||
B3["assets/main.scss"]
|
||||
end
|
||||
V1 --> S1
|
||||
V2 --> S2
|
||||
V3 --> I1
|
||||
V4 --> I1
|
||||
V5 --> I1
|
||||
V6 --> I1
|
||||
S1 --> I2
|
||||
I1 --> I3
|
||||
B1 --> V1
|
||||
B1 --> V2
|
||||
B1 --> V3
|
||||
B1 --> V4
|
||||
B1 --> V5
|
||||
B1 --> V6
|
||||
B1 --> B2
|
||||
B1 --> B3
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
- [views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
|
||||
- [views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
|
||||
- [views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L1-L800)
|
||||
- [views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
|
||||
- [views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
|
||||
- [views/reports/Reports.vue](file://frontend/src/views/reports/Reports.vue#L1-L367)
|
||||
- [assets/main.scss](file://frontend/src/assets/main.scss#L1-L186)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 路由与导航
|
||||
- 路由模式:History 模式,便于 SEO 与语义化 URL。
|
||||
- 导航守卫:在进入非登录页时校验本地 token,未登录自动跳转登录页。
|
||||
- 嵌套路由:Layout 作为父路由,子路由承载各业务页面,支持面包屑标题动态设置。
|
||||
- 动态导入:路由组件懒加载,提升首屏性能。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant R as "路由守卫"
|
||||
participant L as "登录页"
|
||||
participant H as "主页"
|
||||
U->>R : 访问任意受保护路径
|
||||
R->>R : 读取 localStorage 中 token
|
||||
alt 无 token
|
||||
R-->>U : 跳转到 /login
|
||||
U->>L : 渲染登录页
|
||||
else 有 token
|
||||
R-->>U : 放行
|
||||
U->>H : 进入主框架
|
||||
end
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
|
||||
章节来源
|
||||
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
|
||||
### 状态管理(Pinia)
|
||||
- 用户状态:登录、获取当前用户信息、登出;token 持久化至 localStorage。
|
||||
- 应用状态:侧边栏折叠状态、科室树加载;用于菜单渲染与布局切换。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class UserStore {
|
||||
+string token
|
||||
+object userInfo
|
||||
+login(username,password) Promise~boolean~
|
||||
+getUserInfo() Promise~object|null~
|
||||
+logout() void
|
||||
}
|
||||
class AppStore {
|
||||
+boolean collapsed
|
||||
+array departmentTree
|
||||
+toggleSidebar() void
|
||||
+loadDepartmentTree() Promise~void~
|
||||
}
|
||||
class ApiAuth {
|
||||
+login(data) Promise
|
||||
+getCurrentUser() Promise
|
||||
}
|
||||
UserStore --> ApiAuth : "调用"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
|
||||
章节来源
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [stores/index.js](file://frontend/src/stores/index.js#L1-L3)
|
||||
|
||||
### API 调用封装
|
||||
- Axios 实例:baseURL 指向 /api/v1,统一超时与 Content-Type。
|
||||
- 请求拦截:自动附加 Authorization 头(Bearer token)。
|
||||
- 响应拦截:统一错误码判断、错误消息提示、401 自动清理 token 并跳转登录。
|
||||
- 接口模块:按领域拆分(auth、department、staff、indicator、assessment、salary、stats、template),并在 index.js 聚合导出。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["发起请求"]) --> AddToken["从 localStorage 读取 token 并注入 Authorization"]
|
||||
AddToken --> SendReq["发送请求"]
|
||||
SendReq --> Resp{"响应状态"}
|
||||
Resp --> |code!=200| ShowErr["提示错误消息"]
|
||||
Resp --> |401| ClearToken["清除 token 并跳转登录"]
|
||||
Resp --> |其他错误| ShowNetErr["提示网络错误"]
|
||||
Resp --> |成功| ReturnRes["返回响应数据"]
|
||||
ShowErr --> End(["结束"])
|
||||
ClearToken --> End
|
||||
ShowNetErr --> End
|
||||
ReturnRes --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [api/request.js](file://frontend/src/api/request.js#L14-L63)
|
||||
|
||||
章节来源
|
||||
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [api/index.js](file://frontend/src/api/index.js#L1-L9)
|
||||
|
||||
### 登录页与布局
|
||||
- 登录页:表单校验、加载态、错误提示、默认账号演示、登录成功跳转。
|
||||
- 布局:侧边栏菜单、顶部导航、面包屑、内容区过渡动画、用户下拉菜单、退出登录。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant L as "Login.vue"
|
||||
participant S as "UserStore"
|
||||
participant R as "Router"
|
||||
participant A as "Auth API"
|
||||
U->>L : 输入用户名/密码并点击登录
|
||||
L->>L : 表单校验
|
||||
L->>S : 调用 login(username,password)
|
||||
S->>A : 调用登录接口
|
||||
A-->>S : 返回 token
|
||||
S-->>L : 返回 true
|
||||
L->>R : 跳转到 /
|
||||
R-->>U : 渲染 Layout
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [views/Login.vue](file://frontend/src/views/Login.vue#L73-L89)
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L10-L20)
|
||||
- [api/auth.js](file://frontend/src/api/auth.js#L4-L11)
|
||||
- [router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
|
||||
章节来源
|
||||
- [views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
|
||||
- [views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
|
||||
### 工作台(Dashboard)
|
||||
- 统计卡片:在职员工、已考核人数、平均得分、奖金总额。
|
||||
- 关键指标仪表盘:四个 KPI 指标仪表图联动。
|
||||
- 图表区域:科室排名对比、收支趋势、绩效趋势、绩效分布饼图。
|
||||
- 预警提示:低分员工、未完成考核科室、异常数据。
|
||||
- 员工排名:TOP 10 展示与奖金格式化。
|
||||
|
||||
章节来源
|
||||
- [views/Dashboard.vue](file://frontend/src/views/Dashboard.vue#L1-L800)
|
||||
- [assets/main.scss](file://frontend/src/assets/main.scss#L95-L179)
|
||||
|
||||
### 基础数据-科室管理
|
||||
- 查询条件:关键词、科室类型、分页。
|
||||
- 表格字段:编码、名称、类型、层级、状态、创建时间。
|
||||
- 操作:编辑、删除、状态开关。
|
||||
- 新增/编辑弹窗:表单校验、树形上级选择、提交。
|
||||
- 数据加载:分页查询、科室树加载。
|
||||
|
||||
章节来源
|
||||
- [views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
|
||||
|
||||
### 考核管理
|
||||
- 查询条件:科室树选择、考核周期、状态筛选。
|
||||
- 表格字段:姓名、科室、周期、总分、加权得分、状态、创建时间。
|
||||
- 操作:查看详情、提交、审核通过/驳回、确认。
|
||||
- 批量创建:选择科室、周期、指标集合进行批量生成。
|
||||
|
||||
章节来源
|
||||
- [views/assessment/Assessments.vue](file://frontend/src/views/assessment/Assessments.vue#L1-L311)
|
||||
|
||||
### 统计报表
|
||||
- 筛选条件:统计周期(月)。
|
||||
- 统计概览:在职员工、已考核人数、平均得分、奖金总额。
|
||||
- 图表:科室绩效对比柱状图、绩效分布饼图。
|
||||
- 数据表格:科室统计与员工排名 TOP 20。
|
||||
|
||||
章节来源
|
||||
- [views/reports/Reports.vue](file://frontend/src/views/reports/Reports.vue#L1-L367)
|
||||
|
||||
## 依赖关系分析
|
||||
- 依赖安装:Vue 3、Vue Router、Pinia、Axios、Element Plus、图标库、ECharts、Day.js。
|
||||
- 开发依赖:@vitejs/plugin-vue、vite、sass。
|
||||
- 构建与运行:dev/build/preview 脚本,代理 /api 到后端 8000 端口。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
P["package.json"] --> V["vue@^3.4.15"]
|
||||
P --> VR["vue-router@^4.2.5"]
|
||||
P --> PN["pinia@^2.1.7"]
|
||||
P --> AX["axios@^1.6.5"]
|
||||
P --> EP["element-plus@^2.5.3"]
|
||||
P --> IC["@element-plus/icons-vue@^2.3.1"]
|
||||
P --> EC["echarts@^5.4.3"]
|
||||
P --> DJ["dayjs@^1.11.10"]
|
||||
P --> VP["@vitejs/plugin-vue@^5.0.3"]
|
||||
P --> VT["vite@^5.0.11"]
|
||||
P --> SA["sass@^1.70.0"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [package.json](file://frontend/package.json#L11-L25)
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L1-L27)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
|
||||
## 性能考虑
|
||||
- 路由懒加载:使用动态导入减少首屏体积。
|
||||
- 组件懒加载:路由组件按需加载。
|
||||
- 图表性能:ECharts 初始化与 resize 事件绑定,避免重复初始化;图表容器尺寸固定,减少重排。
|
||||
- 状态持久化:用户 token 存储于 localStorage,减少重复登录开销。
|
||||
- 请求缓存:可结合业务场景在 Store 层增加简单缓存策略(如最近一次查询结果)。
|
||||
- 构建优化:生产构建开启压缩与 Tree Shaking;按需引入 Element Plus 组件与图标以减小体积。
|
||||
|
||||
## 故障排查指南
|
||||
- 登录失败/401:检查后端认证接口是否返回 token,确认请求拦截器是否正确注入 Authorization。
|
||||
- 路由跳转异常:确认路由守卫逻辑与 token 存储位置一致。
|
||||
- 图表不显示:确认容器元素存在且具备宽高,窗口 resize 事件触发图表 resize。
|
||||
- 样式冲突:检查全局样式与组件 scoped 样式的优先级,避免覆盖 Element Plus 默认样式。
|
||||
- 代理无效:确认 vite 代理配置指向正确的后端地址与端口。
|
||||
|
||||
章节来源
|
||||
- [api/request.js](file://frontend/src/api/request.js#L14-L63)
|
||||
- [router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [assets/main.scss](file://frontend/src/assets/main.scss#L181-L186)
|
||||
|
||||
## 结论
|
||||
本指南基于现有代码梳理了前端架构与实现细节,建议在后续迭代中持续完善:
|
||||
- 在 Store 中增加更细粒度的错误状态与加载状态管理。
|
||||
- 对高频接口增加缓存策略与防抖。
|
||||
- 逐步引入 TypeScript 以提升类型安全。
|
||||
- 增加单元测试与端到端测试覆盖关键流程。
|
||||
|
||||
## 附录
|
||||
|
||||
### 开发环境配置与热重载
|
||||
- 启动命令:npm run dev
|
||||
- 端口:5173
|
||||
- 代理:/api -> http://localhost:8000
|
||||
- 热重载:Vite 默认启用,修改代码自动刷新
|
||||
|
||||
章节来源
|
||||
- [vite.config.js](file://frontend/vite.config.js#L12-L20)
|
||||
- [package.json](file://frontend/package.json#L6-L10)
|
||||
|
||||
### 生产构建与部署
|
||||
- 构建命令:npm run build
|
||||
- 预览命令:npm run preview
|
||||
- 部署建议:将 dist 目录部署至 Nginx/Apache,确保静态资源路径正确;后端提供 /api/v1 接口。
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L6-L10)
|
||||
|
||||
### Element Plus 使用与样式定制
|
||||
- 全局注册:在入口文件注册 Element Plus 与图标组件。
|
||||
- 国际化:通过 Config Provider 与 zhCN 语言包统一界面语言。
|
||||
- 主题变量:在全局样式中定义颜色与间距变量,供组件样式复用。
|
||||
- 响应式布局:利用 Element Plus Grid 与 Flex 布局实现自适应。
|
||||
|
||||
章节来源
|
||||
- [main.js](file://frontend/src/main.js#L3-L21)
|
||||
- [App.vue](file://frontend/src/App.vue#L2-L8)
|
||||
- [assets/main.scss](file://frontend/src/assets/main.scss#L14-L61)
|
||||
421
.qoder/repowiki/zh/content/前端开发指南/构建与部署.md
Normal file
421
.qoder/repowiki/zh/content/前端开发指南/构建与部署.md
Normal file
@@ -0,0 +1,421 @@
|
||||
# 构建与部署
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [vite.config.js](file://frontend/vite.config.js)
|
||||
- [package.json](file://frontend/package.json)
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md)
|
||||
- [frontend.md](file://docs/frontend.md)
|
||||
- [main.js](file://frontend/src/main.js)
|
||||
- [router/index.js](file://frontend/src/router/index.js)
|
||||
- [api/request.js](file://frontend/src/api/request.js)
|
||||
- [stores/user.js](file://frontend/src/stores/user.js)
|
||||
- [assets/main.scss](file://frontend/src/assets/main.scss)
|
||||
- [test-api.html](file://frontend/public/test-api.html)
|
||||
- [test-api.html](file://frontend/dist/test-api.html)
|
||||
- [test_frontend_connection.py](file://test_frontend_connection.py)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本指南面向前端构建与部署,围绕 Vite 构建配置、环境变量、资源优化、静态资源与代码分割、打包分析、生产构建与 CDN 缓存策略、容器化与 Nginx 反向代理、自动化部署与 CI/CD、版本发布管理、性能监控与错误追踪、用户体验优化以及调试与性能分析方法进行系统化说明。文档同时结合仓库现有前端工程与配套文档,确保内容可落地、可验证。
|
||||
|
||||
## 项目结构
|
||||
前端工程采用 Vite + Vue 3 + Pinia + Element Plus 的现代前端技术栈,源码位于 frontend 目录,构建产物输出至 dist 目录;开发时通过 Vite Dev Server 提供本地服务与代理能力;路由、状态管理、HTTP 客户端等关键模块均在 src 目录下组织。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "前端工程(frontend)"
|
||||
SRC["src 源码<br/>main.js/router/api/stores/assets"]
|
||||
DIST["dist 构建产物"]
|
||||
VCFG["vite.config.js"]
|
||||
PKG["package.json"]
|
||||
PUB["public 静态资源"]
|
||||
end
|
||||
SRC --> VCFG
|
||||
SRC --> PKG
|
||||
VCFG --> DIST
|
||||
PKG --> DIST
|
||||
PUB --> DIST
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
- [package.json](file://frontend/package.json#L1-L27)
|
||||
|
||||
章节来源
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
- [package.json](file://frontend/package.json#L1-L27)
|
||||
- [frontend.md](file://docs/frontend.md#L1-L416)
|
||||
|
||||
## 核心组件
|
||||
- 构建与开发服务器
|
||||
- Vite 插件与别名配置、开发服务器端口与代理规则
|
||||
- 开发脚本、构建脚本与预览脚本
|
||||
- 应用入口与全局依赖
|
||||
- 应用挂载、插件注册、国际化与全局样式引入
|
||||
- 路由与导航
|
||||
- 基于 History 模式的路由配置与前置守卫
|
||||
- 状态管理
|
||||
- Pinia Store 的用户状态与登录流程
|
||||
- HTTP 客户端
|
||||
- Axios 实例、基础地址、超时、请求/响应拦截器与错误处理
|
||||
- 样式与主题
|
||||
- 全局 SCSS 变量、布局与组件样式规范
|
||||
- 调试与测试工具
|
||||
- 内置 API 测试页面与前端连通性测试脚本
|
||||
|
||||
章节来源
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
- [package.json](file://frontend/package.json#L1-L27)
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [assets/main.scss](file://frontend/src/assets/main.scss#L1-L186)
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L1-L119)
|
||||
- [frontend.md](file://docs/frontend.md#L1-L416)
|
||||
|
||||
## 架构总览
|
||||
前端应用通过 Vite 构建,开发时由 Vite Dev Server 提供本地服务与代理,生产时生成静态资源并由 Nginx 提供静态文件服务与反向代理。HTTP 请求通过 Axios 发送,统一拦截处理错误与鉴权逻辑;路由守卫保障登录态校验;Pinia 管理用户状态。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
Browser["浏览器客户端"] --> ViteDev["Vite 开发服务器<br/>端口:5173"]
|
||||
ViteDev --> Proxy["代理规则<br/>/api -> 后端"]
|
||||
Browser --> BuildOut["构建产物 dist/*"]
|
||||
BuildOut --> Nginx["Nginx 反向代理"]
|
||||
Nginx --> Backend["后端服务"]
|
||||
subgraph "前端应用"
|
||||
Axios["Axios 实例<br/>拦截器/错误处理"]
|
||||
Router["Vue Router<br/>前置守卫"]
|
||||
Stores["Pinia Store<br/>用户状态"]
|
||||
end
|
||||
Browser --> Axios
|
||||
Browser --> Router
|
||||
Browser --> Stores
|
||||
Axios --> Proxy
|
||||
Proxy --> Backend
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [vite.config.js](file://frontend/vite.config.js#L12-L20)
|
||||
- [api/request.js](file://frontend/src/api/request.js#L5-L12)
|
||||
- [router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L6-L48)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### Vite 构建与开发服务器
|
||||
- 插件与别名
|
||||
- 使用 Vue 插件与路径别名 @ 指向 src,便于导入
|
||||
- 开发服务器
|
||||
- 端口 5173,默认启用
|
||||
- 代理 /api 到后端地址,解决开发跨域问题
|
||||
- 构建与脚本
|
||||
- 提供 dev/build/preview 三个常用脚本,满足开发、构建与本地预览
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["启动 Vite"]) --> LoadCfg["加载 vite.config.js"]
|
||||
LoadCfg --> Plugins["初始化插件与别名"]
|
||||
Plugins --> DevServer["启动开发服务器<br/>端口:5173"]
|
||||
DevServer --> ProxyRule["配置 /api 代理"]
|
||||
ProxyRule --> Ready(["开发就绪"])
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [vite.config.js](file://frontend/vite.config.js#L5-L21)
|
||||
|
||||
章节来源
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
- [package.json](file://frontend/package.json#L6-L10)
|
||||
|
||||
### 应用入口与全局依赖
|
||||
- 应用挂载与插件
|
||||
- 注册 Pinia、Vue Router、Element Plus 并设置中文语言包
|
||||
- 注册 Element Plus 图标组件
|
||||
- 全局样式
|
||||
- 引入全局 SCSS,包含主题变量、布局与组件样式
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Entry as "main.js"
|
||||
participant App as "Vue 应用"
|
||||
participant Router as "Vue Router"
|
||||
participant Pinia as "Pinia"
|
||||
participant EP as "Element Plus"
|
||||
Entry->>App : createApp(App)
|
||||
Entry->>Pinia : app.use(createPinia())
|
||||
Entry->>Router : app.use(router)
|
||||
Entry->>EP : app.use(ElementPlus, { locale })
|
||||
Entry->>App : mount("#app")
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [main.js](file://frontend/src/main.js#L12-L23)
|
||||
|
||||
章节来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [assets/main.scss](file://frontend/src/assets/main.scss#L1-L186)
|
||||
|
||||
### 路由与导航
|
||||
- 路由配置
|
||||
- 基于 History 模式,定义多级路由与懒加载页面
|
||||
- 前置守卫
|
||||
- 未登录访问受保护路由时重定向至登录页
|
||||
- 动态设置页面标题
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Enter["进入路由"] --> Guard["前置守卫"]
|
||||
Guard --> HasToken{"是否存在 token?"}
|
||||
HasToken --> |是| Allow["放行"]
|
||||
HasToken --> |否| ToLogin["重定向 /login"]
|
||||
Allow --> Render["渲染目标页面"]
|
||||
ToLogin --> End(["结束"])
|
||||
Render --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
|
||||
章节来源
|
||||
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
|
||||
### 状态管理(用户)
|
||||
- 用户状态
|
||||
- 存储 token 与用户信息,提供登录、获取用户信息、登出方法
|
||||
- 登出时清除 token 并跳转登录页
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class UserStore {
|
||||
+string token
|
||||
+object userInfo
|
||||
+login(username, password) Promise~boolean~
|
||||
+getUserInfo() Promise~object|null~
|
||||
+logout() void
|
||||
}
|
||||
class AuthAPI {
|
||||
+login(data) Promise
|
||||
+getCurrentUser() Promise
|
||||
}
|
||||
UserStore --> AuthAPI : "调用"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L6-L48)
|
||||
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
|
||||
章节来源
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
|
||||
### HTTP 客户端与错误处理
|
||||
- Axios 实例
|
||||
- 基础地址指向 /api/v1,统一超时与 Content-Type
|
||||
- 请求拦截器
|
||||
- 自动附加 Bearer Token
|
||||
- 响应拦截器
|
||||
- 统一错误提示与 401 跳转登录
|
||||
- 对不同状态码给出明确提示
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Comp as "组件"
|
||||
participant Store as "Pinia Store"
|
||||
participant API as "API 函数"
|
||||
participant Axios as "Axios 实例"
|
||||
participant Inter as "拦截器"
|
||||
participant BE as "后端"
|
||||
Comp->>Store : 触发业务动作
|
||||
Store->>API : 调用 API 函数
|
||||
API->>Axios : 发起请求
|
||||
Axios->>Inter : 请求拦截器注入 Authorization
|
||||
Inter->>BE : 发送请求
|
||||
BE-->>Inter : 返回响应
|
||||
Inter-->>Axios : 响应拦截器处理
|
||||
Axios-->>API : 返回数据/抛错
|
||||
API-->>Store : 更新状态/提示
|
||||
Store-->>Comp : 视图更新
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [api/request.js](file://frontend/src/api/request.js#L5-L66)
|
||||
|
||||
章节来源
|
||||
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
|
||||
### 样式与主题
|
||||
- 全局变量与主题色
|
||||
- 定义主色、状态色、文本色、边框色与背景色
|
||||
- 布局与组件样式
|
||||
- 侧边栏、头部、主区域、表格、卡片、状态标签、分数等级、图表容器等样式规范
|
||||
|
||||
章节来源
|
||||
- [assets/main.scss](file://frontend/src/assets/main.scss#L1-L186)
|
||||
|
||||
### 调试与测试工具
|
||||
- 内置 API 测试页面
|
||||
- 提供健康检查与登录测试,便于快速验证前后端连通性
|
||||
- 前端连通性测试脚本
|
||||
- 检查 CORS 配置、登录接口可用性与返回值
|
||||
|
||||
章节来源
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L1-L119)
|
||||
- [test-api.html](file://frontend/public/test-api.html#L39-L75)
|
||||
- [test_frontend_connection.py](file://test_frontend_connection.py#L38-L74)
|
||||
|
||||
## 依赖关系分析
|
||||
- 组件耦合
|
||||
- main.js 作为入口,集中注册插件与依赖
|
||||
- router/index.js 与 stores/user.js 彼此独立,通过业务调用交互
|
||||
- api/request.js 作为 HTTP 客户端被各 API 模块复用
|
||||
- 外部依赖
|
||||
- Vue 3、Vue Router、Pinia、Axios、Element Plus、ECharts、Day.js、Vite、Sass
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
Main["main.js"] --> Router["router/index.js"]
|
||||
Main --> Pinia["stores/*"]
|
||||
Main --> EP["Element Plus"]
|
||||
Router --> Views["views/*"]
|
||||
Pinia --> API["api/*"]
|
||||
API --> Request["api/request.js"]
|
||||
Request --> Axios["axios"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L11-L25)
|
||||
|
||||
## 性能考量
|
||||
- 构建与资源优化
|
||||
- 使用 Vite 的原生按需加载与 Tree Shaking,减少初始包体
|
||||
- 将第三方 UI 组件与图表库按需引入,避免全量打包
|
||||
- 代码分割
|
||||
- 路由级懒加载与组件级拆分,配合 Vite 的动态导入实现自然分割
|
||||
- 打包分析
|
||||
- 建议使用 Vite 插件进行体积分析,定位大体积依赖与重复模块
|
||||
- 生产构建
|
||||
- 使用构建脚本生成 dist,开启压缩与哈希命名,便于缓存与回滚
|
||||
- CDN 与缓存
|
||||
- 将静态资源托管至 CDN,设置长缓存与版本化文件名;对 HTML 设置短缓存
|
||||
- 运行时性能
|
||||
- 合理使用虚拟滚动、防抖与节流;对图表与大数据表格进行分页与懒加载
|
||||
|
||||
[本节为通用指导,不直接分析具体文件]
|
||||
|
||||
## 故障排查指南
|
||||
- 常见问题与解决
|
||||
- CORS 错误:属预期行为,检查后端 CORS 配置
|
||||
- 404:检查 Vite 代理配置与后端路由
|
||||
- 500:检查后端日志与数据库状态
|
||||
- Network Error:确认后端服务已启动
|
||||
- 调试步骤
|
||||
- 打开浏览器开发者工具,查看 Console 与 Network
|
||||
- 使用内置 API 测试页面与连通性脚本快速定位问题
|
||||
- 清除浏览器缓存与 localStorage,执行硬刷新
|
||||
- 重启后端与前端开发服务器
|
||||
|
||||
章节来源
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L10-L95)
|
||||
- [test_frontend_connection.py](file://test_frontend_connection.py#L38-L74)
|
||||
|
||||
## 结论
|
||||
本指南基于仓库现有前端工程与文档,系统梳理了 Vite 构建配置、开发代理、HTTP 客户端、路由与状态管理、样式体系与调试工具,并给出了生产构建、CDN 与缓存、容器化与 Nginx 反向代理、自动化部署与版本管理、性能监控与错误追踪、用户体验优化与调试分析的实践建议。建议在实际部署中结合团队规范与基础设施,逐步完善 CI/CD 与监控体系,持续优化构建与运行时性能。
|
||||
|
||||
[本节为总结性内容,不直接分析具体文件]
|
||||
|
||||
## 附录
|
||||
|
||||
### A. Vite 构建与环境变量
|
||||
- 构建脚本
|
||||
- 开发:npm run dev
|
||||
- 构建:npm run build
|
||||
- 预览:npm run preview
|
||||
- 环境变量
|
||||
- 建议通过 .env 文件管理 API 基础地址、CDN 基础路径等,避免硬编码
|
||||
- 在 Vite 中可通过 import.meta.env 访问
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L6-L10)
|
||||
- [frontend.md](file://docs/frontend.md#L380-L394)
|
||||
|
||||
### B. 静态资源处理、代码分割与打包分析
|
||||
- 静态资源
|
||||
- public 目录用于放置无需打包的静态资源;构建后与 dist 对齐
|
||||
- 代码分割
|
||||
- 路由懒加载与组件拆分天然实现分割;可结合 Vite 插件进行可视化分析
|
||||
- 打包分析
|
||||
- 推荐使用 @rollup/plugin-visualizer 或 vite-bundle-analyzer
|
||||
|
||||
章节来源
|
||||
- [frontend.md](file://docs/frontend.md#L17-L48)
|
||||
- [router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
|
||||
### C. 生产构建、CDN 与缓存策略
|
||||
- 生产构建
|
||||
- 使用 npm run build 生成 dist;确保代理与基础路径在生产环境关闭或适配
|
||||
- CDN 与缓存
|
||||
- 将 dist 下静态资源上传至 CDN;HTML 设置短缓存;JS/CSS 设置长缓存并带内容指纹
|
||||
- 反向代理
|
||||
- Nginx 将静态资源交由 Nginx 直接提供,/api 前缀转发至后端
|
||||
|
||||
[本节为通用指导,不直接分析具体文件]
|
||||
|
||||
### D. Docker 容器化与 Nginx 反向代理
|
||||
- 容器化
|
||||
- 使用 Nginx 镜像作为静态资源服务器,挂载 dist 目录
|
||||
- Nginx 配置要点
|
||||
- 静态文件根目录指向 dist
|
||||
- /api 前缀代理至后端服务
|
||||
- 设置缓存与 Gzip 压缩
|
||||
- 反向代理
|
||||
- 将前端域名解析到 Nginx,Nginx 负责静态资源与 API 转发
|
||||
|
||||
[本节为通用指导,不直接分析具体文件]
|
||||
|
||||
### E. 自动化部署、CI/CD 与版本发布
|
||||
- CI/CD
|
||||
- 在流水线中执行安装依赖、构建、测试与部署步骤
|
||||
- 构建产物上传至制品库或直接部署到 Nginx
|
||||
- 版本发布
|
||||
- 使用语义化版本管理;构建产物与版本关联,便于回滚
|
||||
|
||||
[本节为通用指导,不直接分析具体文件]
|
||||
|
||||
### F. 性能监控、错误追踪与用户体验优化
|
||||
- 性能监控
|
||||
- 关注首屏时间、交互延迟与内存占用;结合浏览器性能面板与 Lighthouse
|
||||
- 错误追踪
|
||||
- 前端错误上报与后端错误日志联动;统一错误提示与用户引导
|
||||
- 用户体验
|
||||
- 加载骨架屏、空态与错误态;合理分页与搜索;移动端适配
|
||||
|
||||
[本节为通用指导,不直接分析具体文件]
|
||||
|
||||
### G. 调试工具使用与性能分析
|
||||
- 调试工具
|
||||
- 浏览器开发者工具、Vue DevTools、网络面板、性能面板
|
||||
- 性能分析
|
||||
- 关注资源加载顺序、缓存命中率与关键渲染路径
|
||||
|
||||
章节来源
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L1-L119)
|
||||
330
.qoder/repowiki/zh/content/前端开发指南/状态管理.md
Normal file
330
.qoder/repowiki/zh/content/前端开发指南/状态管理.md
Normal file
@@ -0,0 +1,330 @@
|
||||
# 状态管理
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [frontend/src/main.js](file://frontend/src/main.js)
|
||||
- [frontend/src/stores/index.js](file://frontend/src/stores/index.js)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js)
|
||||
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js)
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js)
|
||||
- [frontend/package.json](file://frontend/package.json)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本指南围绕前端仓库中的 Pinia 状态管理进行系统化讲解,覆盖 Store 的创建、状态与动作的实现、模块化组织、跨组件共享、持久化策略、订阅与调试、异步与错误处理、以及状态重置与迁移等主题。结合项目实际的用户状态与应用配置状态实现,帮助开发者快速理解并高效扩展状态管理能力。
|
||||
|
||||
## 项目结构
|
||||
前端采用 Vue 3 + Pinia 架构,状态管理集中在 stores 目录,通过集中导出统一暴露给视图层;路由负责页面导航与鉴权守卫;API 层封装请求逻辑;入口文件完成 Pinia 的安装与挂载。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "入口与框架"
|
||||
MAIN["main.js<br/>安装 Pinia 并挂载应用"]
|
||||
ROUTER["router/index.js<br/>路由与鉴权守卫"]
|
||||
end
|
||||
subgraph "状态层"
|
||||
STORES_INDEX["stores/index.js<br/>统一导出 Store"]
|
||||
USER["stores/user.js<br/>用户状态 Store"]
|
||||
APP["stores/app.js<br/>应用配置 Store"]
|
||||
end
|
||||
subgraph "视图层"
|
||||
LOGIN["views/Login.vue<br/>登录页"]
|
||||
LAYOUT["views/Layout.vue<br/>布局页"]
|
||||
end
|
||||
subgraph "API 层"
|
||||
AUTH_API["api/auth.js<br/>认证接口"]
|
||||
DEPT_API["api/department.js<br/>科室接口"]
|
||||
end
|
||||
MAIN --> STORES_INDEX
|
||||
STORES_INDEX --> USER
|
||||
STORES_INDEX --> APP
|
||||
LOGIN --> USER
|
||||
LAYOUT --> APP
|
||||
USER --> AUTH_API
|
||||
APP --> DEPT_API
|
||||
ROUTER --> LOGIN
|
||||
ROUTER --> LAYOUT
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [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/views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [frontend/src/stores/index.js](file://frontend/src/stores/index.js#L1-L3)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
|
||||
## 核心组件
|
||||
- 用户状态 Store(user)
|
||||
- 状态:令牌与用户信息
|
||||
- 动作:登录、获取用户信息、登出
|
||||
- 持久化:本地存储令牌
|
||||
- 应用配置 Store(app)
|
||||
- 状态:侧边栏折叠状态、科室树
|
||||
- 动作:切换侧边栏、加载科室树
|
||||
- 统一导出(stores/index.js)
|
||||
- 集中导出各 Store,便于视图层按需引入
|
||||
- 入口与安装(main.js)
|
||||
- 安装 Pinia 插件并挂载到根实例
|
||||
- 路由与鉴权(router/index.js)
|
||||
- 登录页与受保护页面的导航控制
|
||||
- API 层(api/auth.js、api/department.js)
|
||||
- 对后端接口的封装,供 Store 动作调用
|
||||
|
||||
章节来源
|
||||
- [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/main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
|
||||
## 架构总览
|
||||
以下序列图展示登录流程中,视图层、用户 Store 与 API 层之间的交互,体现异步状态处理与错误反馈。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant V as "Login.vue"
|
||||
participant US as "useUserStore"
|
||||
participant API as "auth.js"
|
||||
participant RT as "router/index.js"
|
||||
V->>US : "login(用户名, 密码)"
|
||||
US->>API : "POST /auth/login"
|
||||
API-->>US : "返回访问令牌"
|
||||
US->>US : "写入令牌到本地存储"
|
||||
US-->>V : "返回登录结果"
|
||||
V->>RT : "跳转至首页"
|
||||
Note over V,RT : "若登录失败,显示错误提示"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [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/api/auth.js](file://frontend/src/api/auth.js#L4-L11)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 用户状态 Store(user)
|
||||
- 状态定义
|
||||
- 令牌:用于鉴权,初始化从本地存储读取
|
||||
- 用户信息:当前登录用户的资料
|
||||
- 动作方法
|
||||
- 登录:调用认证接口,成功后写入令牌并持久化
|
||||
- 获取用户信息:拉取当前用户资料
|
||||
- 登出:清空令牌与用户信息,跳转登录页
|
||||
- 最佳实践
|
||||
- 在登录动作中捕获异常并返回布尔值,便于视图层判断
|
||||
- 登出时同步清理本地存储与路由跳转,保证状态一致性
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["进入登录动作"]) --> CallAPI["调用认证接口"]
|
||||
CallAPI --> Success{"请求成功?"}
|
||||
Success --> |是| SetToken["写入令牌到状态与本地存储"]
|
||||
Success --> |否| ReturnFalse["返回失败标记"]
|
||||
SetToken --> Done(["结束"])
|
||||
ReturnFalse --> Done
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L11-L20)
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L4-L11)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [frontend/src/api/auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
|
||||
### 应用配置 Store(app)
|
||||
- 状态定义
|
||||
- 侧边栏折叠状态:控制菜单宽度与显示
|
||||
- 科室树:后端返回的树形结构,用于菜单生成
|
||||
- 动作方法
|
||||
- 切换侧边栏:翻转折叠状态
|
||||
- 加载科室树:调用接口获取数据并赋值
|
||||
- 最佳实践
|
||||
- 在加载动作中使用 try/catch 处理异常,避免未捕获错误导致界面卡死
|
||||
- 数据为空时提供兜底逻辑,确保 UI 正常渲染
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["进入加载科室树"]) --> TryCall["调用接口获取数据"]
|
||||
TryCall --> Try{"请求成功?"}
|
||||
Try --> |是| Assign["赋值到状态"]
|
||||
Try --> |否| Catch["记录错误日志"]
|
||||
Assign --> End(["结束"])
|
||||
Catch --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L15-L22)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L9-L11)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [frontend/src/api/department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
|
||||
### 视图层集成与跨组件共享
|
||||
- 登录页(Login.vue)
|
||||
- 引入用户 Store,绑定表单校验与加载态
|
||||
- 调用登录动作,根据返回结果进行消息提示与路由跳转
|
||||
- 布局页(Layout.vue)
|
||||
- 引入应用 Store,控制侧边栏折叠与菜单渲染
|
||||
- 引入用户 Store,触发登出动作
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant LV as "Login.vue"
|
||||
participant UV as "useUserStore"
|
||||
LV->>UV : "login()"
|
||||
UV-->>LV : "true/false"
|
||||
LV->>LV : "提示与路由跳转"
|
||||
participant LV2 as "Layout.vue"
|
||||
participant AV as "useAppStore"
|
||||
LV2->>AV : "toggleSidebar()"
|
||||
LV2->>AV : "loadDepartmentTree()"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L55-L89)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L76-L124)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L11-L20)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L10-L22)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L1-L155)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
|
||||
|
||||
### 模块化组织与统一导出
|
||||
- stores/index.js 将各 Store 统一导出,便于视图层按需引入,降低导入分散带来的维护成本
|
||||
- 建议后续可扩展计算属性与插件化注册,进一步增强模块化能力
|
||||
|
||||
章节来源
|
||||
- [frontend/src/stores/index.js](file://frontend/src/stores/index.js#L1-L3)
|
||||
|
||||
### 状态持久化策略
|
||||
- 令牌持久化:登录成功后写入本地存储,刷新页面后仍可保持登录态
|
||||
- 状态持久化建议:
|
||||
- 对于轻量配置(如侧边栏折叠),可仅做内存持久化并在必要时写入本地存储
|
||||
- 对于重要业务数据,优先通过后端接口拉取,前端仅做缓存与回退处理
|
||||
|
||||
章节来源
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L7-L16)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L6-L7)
|
||||
|
||||
### 状态订阅与调试
|
||||
- 订阅:可通过 Pinia 提供的订阅机制监听状态变化,便于调试与副作用处理
|
||||
- 调试:结合浏览器开发工具查看 Store 状态与动作调用链,定位问题
|
||||
- 建议:在开发环境开启严格模式与日志输出,生产环境关闭冗余日志
|
||||
|
||||
(本节为通用指导,不直接分析具体文件)
|
||||
|
||||
### 异步状态处理、错误状态管理与加载状态控制
|
||||
- 异步处理:Store 动作统一使用 async/await,确保调用方能正确等待结果
|
||||
- 错误处理:在动作内部捕获异常并返回明确的结果标识,视图层据此给出反馈
|
||||
- 加载状态:视图层维护加载态变量,在动作执行前后切换,提升用户体验
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L77-L88)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L11-L20)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L15-L22)
|
||||
|
||||
### 状态重置、合并与迁移策略
|
||||
- 重置:登出时清空令牌与用户信息,恢复初始状态
|
||||
- 合并:加载新数据时先清空旧数据再赋值,避免脏数据残留
|
||||
- 迁移:当后端字段变更时,Store 中提供兼容逻辑或版本化处理,保证向前兼容
|
||||
|
||||
章节来源
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L34-L39)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L15-L22)
|
||||
|
||||
## 依赖关系分析
|
||||
- 入口依赖:main.js 依赖 Pinia 安装,确保全局可用
|
||||
- 视图依赖:Login.vue 依赖 user Store,Layout.vue 依赖 app Store
|
||||
- Store 依赖:user Store 依赖 auth API,app Store 依赖 department API
|
||||
- 路由依赖:router/index.js 依赖本地存储令牌进行鉴权守卫
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
MAIN["main.js"] --> PINIA["Pinia"]
|
||||
LOGIN["Login.vue"] --> USER["useUserStore"]
|
||||
LAYOUT["Layout.vue"] --> APP["useAppStore"]
|
||||
USER --> AUTH["auth.js"]
|
||||
APP --> DEPT["department.js"]
|
||||
ROUTER["router/index.js"] --> TOKEN["localStorage(token)"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/main.js](file://frontend/src/main.js#L19-L19)
|
||||
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L55-L58)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L76-L81)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L3-L4)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L3-L3)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L106-L108)
|
||||
|
||||
章节来源
|
||||
- [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#L11-L20)
|
||||
|
||||
## 性能考量
|
||||
- 状态粒度:将高频更新与低频更新拆分到不同 Store 或状态字段,减少不必要的响应式开销
|
||||
- 异步批处理:对频繁触发的动作进行防抖或节流,避免重复请求
|
||||
- 缓存策略:对只读或稳定数据(如科室树)进行本地缓存,降低网络请求频率
|
||||
- 渲染优化:在视图层避免深层嵌套的响应式对象,尽量扁平化状态结构
|
||||
|
||||
(本节为通用指导,不直接分析具体文件)
|
||||
|
||||
## 故障排查指南
|
||||
- 登录失败
|
||||
- 检查登录动作是否抛出异常并返回布尔值
|
||||
- 核对 API 返回结构与 Store 写入逻辑
|
||||
- 无法跳转
|
||||
- 确认路由守卫逻辑与本地存储令牌状态一致
|
||||
- 侧边栏不生效
|
||||
- 检查 Store 折叠状态与视图绑定是否正确
|
||||
- 科室树不显示
|
||||
- 确认接口返回结构与赋值逻辑一致,必要时添加兜底数据
|
||||
|
||||
章节来源
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L11-L20)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L4-L25)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js#L15-L22)
|
||||
|
||||
## 结论
|
||||
本项目基于 Pinia 实现了清晰的用户状态与应用配置状态管理,配合统一导出与路由守卫,形成了模块化、可扩展且易于维护的状态体系。遵循本文的最佳实践与策略,可在保证性能与可维护性的前提下,进一步完善异步处理、错误管理与调试能力。
|
||||
|
||||
## 附录
|
||||
- 关键实现位置参考
|
||||
- 用户登录与登出:[frontend/src/stores/user.js](file://frontend/src/stores/user.js#L11-L39)
|
||||
- 应用配置与菜单加载:[frontend/src/stores/app.js](file://frontend/src/stores/app.js#L15-L22)
|
||||
- 视图层集成示例:[frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L73-L89)、[frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L76-L124)
|
||||
- 入口与安装:[frontend/src/main.js](file://frontend/src/main.js#L19-L19)
|
||||
- 路由与鉴权:[frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- API 封装:[frontend/src/api/auth.js](file://frontend/src/api/auth.js#L4-L11)、[frontend/src/api/department.js](file://frontend/src/api/department.js#L9-L11)
|
||||
315
.qoder/repowiki/zh/content/前端开发指南/路由与导航.md
Normal file
315
.qoder/repowiki/zh/content/前端开发指南/路由与导航.md
Normal file
@@ -0,0 +1,315 @@
|
||||
# 路由与导航
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js)
|
||||
- [frontend/src/main.js](file://frontend/src/main.js)
|
||||
- [frontend/src/App.vue](file://frontend/src/App.vue)
|
||||
- [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/user.js](file://frontend/src/stores/user.js)
|
||||
- [frontend/src/stores/app.js](file://frontend/src/stores/app.js)
|
||||
- [frontend/src/api/menu.js](file://frontend/src/api/menu.js)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js)
|
||||
- [frontend/src/views/assessment/AssessmentDetail.vue](file://frontend/src/views/assessment/AssessmentDetail.vue)
|
||||
- [frontend/package.json](file://frontend/package.json)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件系统化梳理了 Vue Router 在本项目中的路由管理实践,覆盖路由配置、嵌套路由、动态路由、路由守卫与权限拦截、参数传递与查询字符串处理、路由元信息、面包屑与侧边栏联动、页面标题动态更新、懒加载与代码分割、登录态保持与权限控制、以及页面缓存策略等主题。旨在帮助开发者快速理解并扩展路由体系。
|
||||
|
||||
## 项目结构
|
||||
前端采用 Vite + Vue 3 + vue-router 4 + Pinia 的现代前端栈,路由集中于 router/index.js,视图组件位于 views 下,状态管理位于 stores,HTTP 请求封装于 api/request.js 并通过 axios 实现拦截器。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A["入口 main.js"] --> B["应用 App.vue"]
|
||||
A --> C["路由 router/index.js"]
|
||||
C --> D["布局 Layout.vue"]
|
||||
D --> E["侧边栏菜单<br/>动态加载"]
|
||||
D --> F["面包屑<br/>基于 meta.title"]
|
||||
D --> G["主内容区 router-view"]
|
||||
G --> H["各业务视图<br/>如 Login.vue / Dashboard.vue / AssessmentDetail.vue"]
|
||||
A --> I["状态 stores<br/>user.js / app.js"]
|
||||
A --> J["HTTP 封装 api/request.js"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [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/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/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
|
||||
## 核心组件
|
||||
- 路由定义与守卫:集中于 router/index.js,包含基础路由、嵌套路由、动态路由、全局前置守卫。
|
||||
- 应用入口与挂载:main.js 完成插件注册、路由挂载与国际化配置。
|
||||
- 布局与导航:Layout.vue 提供侧边栏菜单、面包屑、头部用户信息与内容区过渡动画。
|
||||
- 登录与权限:Login.vue 负责登录交互;user.js 管理 token 与登录态;全局守卫进行未登录拦截。
|
||||
- 状态管理:app.js 管理侧边栏折叠与部门树;user.js 管理用户信息与登出跳转。
|
||||
- HTTP 封装:request.js 统一添加 Authorization 头、处理 401/403/404/500 等响应错误并重定向到登录。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [frontend/src/main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [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/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/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
|
||||
## 架构总览
|
||||
路由层负责页面级导航与权限控制;布局层负责 UI 结构与导航元素;状态层负责登录态与侧边栏状态;HTTP 层统一处理鉴权头与错误响应。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as "用户"
|
||||
participant R as "路由守卫<br/>router.beforeEach"
|
||||
participant L as "登录页<br/>Login.vue"
|
||||
participant S as "状态 stores<br/>user.js"
|
||||
participant M as "主布局<br/>Layout.vue"
|
||||
U->>R : 访问任意受保护路由
|
||||
R->>R : 读取 localStorage.token
|
||||
alt 未登录且非 /login
|
||||
R-->>U : 重定向至 /login
|
||||
else 已登录或访问 /login
|
||||
R-->>M : 放行并渲染布局
|
||||
end
|
||||
U->>L : 输入凭据并提交
|
||||
L->>S : 调用 userStore.login(...)
|
||||
S-->>L : 成功则写入 token 并跳转 /
|
||||
L-->>M : 渲染主布局
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [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/Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 路由配置与嵌套路由
|
||||
- 基础路由:登录页与根路径重定向。
|
||||
- 嵌套路由:根路径下包含 dashboard、基础数据、考核、工资、报表、财务、计划、系统管理等模块;系统管理内部再嵌套菜单管理。
|
||||
- 路由元信息:每个路由配置了 meta.title、icon 等,用于面包屑与侧边栏展示。
|
||||
- 默认重定向:访问根路径时自动跳转到 dashboard。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L3-L96)
|
||||
|
||||
### 动态路由与菜单联动
|
||||
- 后端菜单树:通过 api/menu.js 的 getMenuTree 接口拉取菜单树,转换为前端可用的菜单项数组。
|
||||
- 侧边栏渲染:Layout.vue 中根据 menuItems 渲染 el-menu,支持折叠与图标显示。
|
||||
- 回退菜单:若拉取失败,使用默认菜单作为后备,保证可用性。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L86-L124)
|
||||
- [frontend/src/api/menu.js](file://frontend/src/api/menu.js#L4-L6)
|
||||
|
||||
### 动态路由参数与详情页
|
||||
- 动态路由:/assessments/:id 对应 AssessmentDetail 页面。
|
||||
- 参数读取:在 AssessmentDetail.vue 中通过 useRoute().params.id 获取动态参数。
|
||||
- 查询字符串:当前示例未使用查询参数,但可通过 useRoute().query 获取。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L52-L56)
|
||||
- [frontend/src/views/assessment/AssessmentDetail.vue](file://frontend/src/views/assessment/AssessmentDetail.vue#L104-L158)
|
||||
|
||||
### 路由元信息与面包屑
|
||||
- 元信息:每个路由的 meta.title 用于页面标题与面包屑显示。
|
||||
- 面包屑:Layout.vue 中直接使用 route.meta.title 作为当前面包屑文本。
|
||||
- 页面标题:全局守卫在每次导航前设置 document.title。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L8-L20)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L104-L106)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L39-L42)
|
||||
|
||||
### 路由守卫、权限验证与导航拦截
|
||||
- 全局前置守卫:router.beforeEach 读取 token,未登录且访问非 /login 路由时强制跳转登录。
|
||||
- 登录成功:Login.vue 调用 userStore.login,成功后写入 token 并跳转根路径。
|
||||
- 登出:user.js 中 logout 清空 token 并跳转 /login。
|
||||
- HTTP 层拦截:request.js 在 401 时清除 token 并跳转 /login,确保前后端一致。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["进入 beforeEach"]) --> ReadToken["读取 localStorage.token"]
|
||||
ReadToken --> IsLogin{"是否已登录?"}
|
||||
IsLogin --> |是| Next["放行 next()"]
|
||||
IsLogin --> |否| IsLoginPage{"是否访问 /login?"}
|
||||
IsLoginPage --> |是| Next
|
||||
IsLoginPage --> |否| ToLogin["next('/login')"]
|
||||
Next --> End(["结束"])
|
||||
ToLogin --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L73-L89)
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L34-L39)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L39-L44)
|
||||
|
||||
### 页面标题动态更新
|
||||
- 标题来源:全局守卫根据 to.meta.title 设置 document.title,并附加系统名。
|
||||
- 建议:可在路由 meta 中补充更完整的标题链路,便于多级标题展示。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L104-L106)
|
||||
|
||||
### 面包屑导航与侧边栏菜单
|
||||
- 面包屑:Layout.vue 使用 route.meta.title 显示当前页面标题。
|
||||
- 侧边栏:Layout.vue 通过 api/menu.js 拉取菜单树,渲染 el-menu;支持折叠与图标。
|
||||
- 菜单回退:若接口异常,使用默认菜单保障可用性。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L39-L42)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L86-L124)
|
||||
- [frontend/src/api/menu.js](file://frontend/src/api/menu.js#L4-L6)
|
||||
|
||||
### 页面缓存机制
|
||||
- 当前实现:Layout.vue 使用 <router-view> 包裹并配合过渡动画,未见显式 keep-alive 缓存策略。
|
||||
- 建议:对频繁切换但无需刷新的页面(如列表页)可引入 keep-alive 以提升体验。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L63-L67)
|
||||
|
||||
### 登录状态保持与权限控制
|
||||
- 登录态:token 存储于 localStorage,user.js 提供 login/getUserInfo/logout。
|
||||
- 权限控制:全局守卫 + HTTP 401 自动登出,确保未授权访问被拦截。
|
||||
- 用户信息:userStore.getUserInfo 用于初始化用户信息,但当前布局未消费该数据。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/stores/user.js](file://frontend/src/stores/user.js#L7-L31)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L39-L44)
|
||||
|
||||
### 路由懒加载与代码分割
|
||||
- 路由级懒加载:各路由 component 使用函数返回动态 import,实现按需加载与代码分割。
|
||||
- 性能收益:首屏仅加载必要模块,减少初始包体积。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L7-L8)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L18)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L24)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L30)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L36)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L42)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L48)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L54)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L60)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L66)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L72)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L78)
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L89)
|
||||
|
||||
### 查询字符串处理
|
||||
- 当前路由未使用查询参数示例;如需使用,可在组件中通过 useRoute().query 获取。
|
||||
- 建议:对需要持久化的筛选条件,优先使用查询参数,利于分享与刷新恢复。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/views/assessment/AssessmentDetail.vue](file://frontend/src/views/assessment/AssessmentDetail.vue#L104-L158)
|
||||
|
||||
## 依赖关系分析
|
||||
- 路由依赖:router/index.js 依赖 Vue Router 与本地组件;全局守卫依赖 localStorage。
|
||||
- 视图依赖:Layout.vue 依赖 stores 与 api/menu.js;Login.vue 依赖 stores/user.js 与 router。
|
||||
- 状态依赖:user.js 依赖 api/auth 与 router;app.js 依赖 api/department。
|
||||
- HTTP 依赖:api/request.js 依赖 axios,并向 router 注入 401 自动登出逻辑。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
R["router/index.js"] --> V1["views/Login.vue"]
|
||||
R --> V2["views/Layout.vue"]
|
||||
V2 --> S1["stores/user.js"]
|
||||
V2 --> S2["stores/app.js"]
|
||||
V2 --> A1["api/menu.js"]
|
||||
V1 --> S1
|
||||
S1 --> A2["api/auth (未在仓库中)"]
|
||||
A1 --> A3["后端 /menus* 接口"]
|
||||
R --> R2["全局守卫使用 localStorage"]
|
||||
R --> A4["api/request.js"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [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/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/menu.js](file://frontend/src/api/menu.js#L1-L37)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
|
||||
章节来源
|
||||
- [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/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/menu.js](file://frontend/src/api/menu.js#L1-L37)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
|
||||
## 性能考虑
|
||||
- 路由懒加载:已通过动态 import 实现按需加载,建议结合路由级命名与路由表拆分进一步优化打包。
|
||||
- 过渡动画:Layout.vue 已启用淡入淡出过渡,避免白屏与闪烁。
|
||||
- 首屏优化:将高频但非首屏使用的路由组件继续延迟加载,减少首屏 JS 体积。
|
||||
- 缓存策略:对列表类页面引入 keep-alive,减少重复渲染与请求开销。
|
||||
- 图标与第三方库:Element Plus 图标已全局注册,避免重复导入。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L7-L8)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L63-L67)
|
||||
- [frontend/package.json](file://frontend/package.json#L11-L25)
|
||||
|
||||
## 故障排查指南
|
||||
- 无法进入受保护页面
|
||||
- 检查 localStorage 是否存在 token;确认全局守卫逻辑与路由路径匹配。
|
||||
- 登录后未跳转
|
||||
- 检查 Login.vue 中调用 userStore.login 返回值与 router.push('/') 执行。
|
||||
- 401 自动登出后未回到登录页
|
||||
- 检查 request.js 响应拦截器是否正确清除 token 并跳转 /login。
|
||||
- 面包屑不显示
|
||||
- 确认目标路由 meta.title 是否配置;Layout.vue 是否使用 route.meta.title。
|
||||
- 侧边栏菜单为空
|
||||
- 检查 api/menu.js 接口返回结构与 Layout.vue 转换逻辑;关注异常回退分支。
|
||||
|
||||
章节来源
|
||||
- [frontend/src/router/index.js](file://frontend/src/router/index.js#L103-L113)
|
||||
- [frontend/src/views/Login.vue](file://frontend/src/views/Login.vue#L73-L89)
|
||||
- [frontend/src/api/request.js](file://frontend/src/api/request.js#L39-L44)
|
||||
- [frontend/src/views/Layout.vue](file://frontend/src/views/Layout.vue#L86-L124)
|
||||
|
||||
## 结论
|
||||
本项目的路由体系以简洁清晰的方式实现了基础导航、嵌套与动态路由、全局守卫与权限拦截、元信息驱动的面包屑与标题、以及基于懒加载的代码分割。后续可在菜单树结构、页面缓存策略、查询参数与面包屑链路等方面进一步增强,以满足更复杂的业务场景与用户体验需求。
|
||||
|
||||
## 附录
|
||||
- 技术栈版本参考
|
||||
- Vue 3、Vue Router 4、Pinia、Element Plus、Axios、Vite
|
||||
- 建议的后续改进方向
|
||||
- 菜单树结构标准化与权限位映射
|
||||
- 面包屑链路与路由层级联动
|
||||
- 页面级 keep-alive 缓存策略
|
||||
- 查询参数与路由参数的规范使用
|
||||
|
||||
章节来源
|
||||
- [frontend/package.json](file://frontend/package.json#L11-L25)
|
||||
483
.qoder/repowiki/zh/content/前端开发指南/项目初始化与配置.md
Normal file
483
.qoder/repowiki/zh/content/前端开发指南/项目初始化与配置.md
Normal file
@@ -0,0 +1,483 @@
|
||||
# 项目初始化与配置
|
||||
|
||||
<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)
|
||||
- [index.js](file://frontend/src/router/index.js)
|
||||
- [main.scss](file://frontend/src/assets/main.scss)
|
||||
- [index.js](file://frontend/src/stores/index.js)
|
||||
- [app.js](file://frontend/src/stores/app.js)
|
||||
- [user.js](file://frontend/src/stores/user.js)
|
||||
- [index.html](file://frontend/index.html)
|
||||
- [request.js](file://frontend/src/api/request.js)
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue)
|
||||
- [Login.vue](file://frontend/src/views/Login.vue)
|
||||
- [auth.js](file://frontend/src/api/auth.js)
|
||||
- [department.js](file://frontend/src/api/department.js)
|
||||
- [menu.js](file://frontend/src/api/menu.js)
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构概览](#架构概览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件面向前端开发者,系统化阐述 Vue 3 应用的创建、初始化与配置流程,涵盖项目结构、依赖管理、Vite 构建与开发服务器配置、Element Plus 主题与国际化设置、全局样式引入、应用入口配置、插件注册与全局组件挂载等。同时提供开发环境搭建步骤、依赖安装命令、启动流程、常见配置问题解决方案以及性能优化建议。
|
||||
|
||||
## 项目结构
|
||||
前端项目位于 `frontend` 目录,采用典型的 Vue 3 + Vite 单页应用结构:
|
||||
- 根目录包含构建脚本、依赖声明与 Vite 配置
|
||||
- `src` 目录包含应用源代码:入口文件、路由、状态管理、API 层、视图组件与全局样式
|
||||
- `public` 目录用于存放静态资源
|
||||
- `dist` 目录为构建产物输出目录
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A["frontend/"] --> B["package.json"]
|
||||
A --> C["vite.config.js"]
|
||||
A --> D["index.html"]
|
||||
A --> E["src/"]
|
||||
E --> F["main.js"]
|
||||
E --> G["App.vue"]
|
||||
E --> H["router/index.js"]
|
||||
E --> I["stores/"]
|
||||
E --> J["api/"]
|
||||
E --> K["views/"]
|
||||
E --> L["assets/main.scss"]
|
||||
A --> M["dist/"]
|
||||
A --> N["public/"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [package.json](file://frontend/package.json#L1-L27)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
- [index.html](file://frontend/index.html#L1-L14)
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L1-L27)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
- [index.html](file://frontend/index.html#L1-L14)
|
||||
|
||||
## 核心组件
|
||||
本节聚焦于项目初始化的关键配置与组件,包括依赖管理、构建配置、应用入口、路由与状态管理、API 层与样式系统。
|
||||
|
||||
- 依赖管理与脚本
|
||||
- 生产依赖:Vue 3、Vue Router、Pinia、Axios、Element Plus、图标库、ECharts、Day.js
|
||||
- 开发依赖:@vitejs/plugin-vue、Vite、Sass
|
||||
- 脚本命令:dev、build、preview
|
||||
- Vite 配置
|
||||
- 插件:Vue 插件
|
||||
- 路径别名:@ 指向 src
|
||||
- 开发服务器:端口 5173,代理 /api 到后端 8000 端口
|
||||
- 应用入口与插件注册
|
||||
- 创建应用实例,注册 Pinia、路由、Element Plus(中文本地化)
|
||||
- 动态注册 Element Plus 图标组件
|
||||
- 引入全局样式 main.scss
|
||||
- 路由与导航
|
||||
- 基于 History 模式的路由,包含登录页与多级菜单路由
|
||||
- 路由守卫:设置页面标题、校验登录状态
|
||||
- 状态管理
|
||||
- Pinia Store:用户状态(token、用户信息)、应用状态(侧边栏折叠、科室树)
|
||||
- API 层
|
||||
- Axios 实例封装:统一 base URL、超时、请求/响应拦截器、错误处理
|
||||
- 认证、菜单、科室等 API 模块
|
||||
- 全局样式
|
||||
- SCSS 变量、布局容器、表格、搜索栏、统计卡片、状态标签、分数等级、图表容器等
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L6-L25)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L5-L21)
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [main.scss](file://frontend/src/assets/main.scss#L1-L186)
|
||||
|
||||
## 架构概览
|
||||
前端采用“入口文件 -> 插件注册 -> 路由与状态管理 -> 视图组件 -> API 层 -> 全局样式”的线性架构,结合 Element Plus 提供 UI 能力与国际化支持。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "应用入口"
|
||||
M["main.js"]
|
||||
A["App.vue"]
|
||||
end
|
||||
subgraph "核心框架"
|
||||
R["Vue Router"]
|
||||
S["Pinia"]
|
||||
EP["Element Plus"]
|
||||
end
|
||||
subgraph "业务层"
|
||||
V["Views"]
|
||||
API["API Modules"]
|
||||
ST["Stores"]
|
||||
end
|
||||
subgraph "基础设施"
|
||||
VITE["Vite Dev Server"]
|
||||
CONF["vite.config.js"]
|
||||
PKG["package.json"]
|
||||
end
|
||||
M --> A
|
||||
M --> R
|
||||
M --> S
|
||||
M --> EP
|
||||
A --> V
|
||||
V --> API
|
||||
V --> ST
|
||||
API --> |"Axios"| API
|
||||
VITE --> CONF
|
||||
PKG --> VITE
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [App.vue](file://frontend/src/App.vue#L1-L17)
|
||||
- [index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L1-L22)
|
||||
- [package.json](file://frontend/package.json#L1-L27)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 依赖管理与脚本
|
||||
- 生产依赖
|
||||
- Vue 3:核心框架
|
||||
- Vue Router:前端路由
|
||||
- Pinia:状态管理
|
||||
- Axios:HTTP 客户端
|
||||
- Element Plus:UI 组件库
|
||||
- @element-plus/icons-vue:图标库
|
||||
- ECharts:可视化图表
|
||||
- Day.js:日期时间处理
|
||||
- 开发依赖
|
||||
- @vitejs/plugin-vue:Vite 的 Vue 支持
|
||||
- Vite:构建工具与开发服务器
|
||||
- Sass:CSS 预处理器
|
||||
- 脚本命令
|
||||
- dev:启动开发服务器
|
||||
- build:构建生产包
|
||||
- preview:预览构建产物
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L11-L25)
|
||||
|
||||
### Vite 构建工具与开发服务器配置
|
||||
- 插件:启用 Vue 插件以支持单文件组件
|
||||
- 路径别名:@ 指向 src,便于导入
|
||||
- 开发服务器:
|
||||
- 端口:5173
|
||||
- 代理:将 /api 前缀转发至后端 8000 端口,解决跨域问题
|
||||
- 该配置确保开发时前后端联调顺畅
|
||||
|
||||
章节来源
|
||||
- [vite.config.js](file://frontend/vite.config.js#L5-L21)
|
||||
|
||||
### 应用入口文件与插件注册
|
||||
- 创建应用实例并挂载根组件
|
||||
- 插件注册顺序:
|
||||
- Pinia(状态管理)
|
||||
- Vue Router(路由)
|
||||
- Element Plus(UI 组件库,使用中文本地化)
|
||||
- 动态注册 Element Plus 图标组件,避免逐个手动注册
|
||||
- 引入全局样式 main.scss
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Browser as "浏览器"
|
||||
participant HTML as "index.html"
|
||||
participant Main as "main.js"
|
||||
participant App as "App.vue"
|
||||
participant Router as "router/index.js"
|
||||
participant Store as "stores/*"
|
||||
participant EP as "Element Plus"
|
||||
Browser->>HTML : 加载页面
|
||||
HTML->>Main : 执行入口脚本
|
||||
Main->>Main : 创建应用实例
|
||||
Main->>EP : 注册 Element Plus(中文)
|
||||
Main->>Main : 动态注册图标组件
|
||||
Main->>Store : 使用 Pinia
|
||||
Main->>Router : 使用 Vue Router
|
||||
Main->>App : 挂载根组件
|
||||
App-->>Browser : 渲染界面
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [index.html](file://frontend/index.html#L10-L11)
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [App.vue](file://frontend/src/App.vue#L1-L17)
|
||||
- [index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
|
||||
章节来源
|
||||
- [index.html](file://frontend/index.html#L1-L14)
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [App.vue](file://frontend/src/App.vue#L1-L17)
|
||||
|
||||
### Element Plus 主题配置与国际化
|
||||
- 国际化:通过 zh-cn.mjs 设置 Element Plus 语言为中文,并在根组件中使用 el-config-provider 包裹,确保全局组件显示中文
|
||||
- 样式:引入 element-plus/dist/index.css 以加载默认样式
|
||||
- 图标:动态注册 Element Plus 图标组件,减少手动注册工作量
|
||||
|
||||
章节来源
|
||||
- [main.js](file://frontend/src/main.js#L3-L6)
|
||||
- [App.vue](file://frontend/src/App.vue#L2-L4)
|
||||
|
||||
### 全局样式引入与主题变量
|
||||
- 全局样式:在入口文件引入 main.scss,实现全局重置、字体、布局容器与通用组件样式
|
||||
- 主题变量:定义主色、状态色、文本色、边框色、背景色等 CSS 变量,便于统一主题风格
|
||||
- 组件级样式:表格、搜索栏、统计卡片、状态标签、分数等级、图表容器等样式集中维护
|
||||
|
||||
章节来源
|
||||
- [main.js](file://frontend/src/main.js#L10-L10)
|
||||
- [main.scss](file://frontend/src/assets/main.scss#L14-L26)
|
||||
- [main.scss](file://frontend/src/assets/main.scss#L63-L186)
|
||||
|
||||
### 路由与导航
|
||||
- 路由结构:
|
||||
- 登录页:/login
|
||||
- 主布局:/,包含工作台、科室管理、员工管理、考核指标、指标模板、考核管理、工资核算、统计报表、经济核算、绩效计划、系统管理(菜单管理)等子路由
|
||||
- 路由守卫:
|
||||
- 设置页面标题
|
||||
- 校验 token,未登录跳转至登录页
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["进入路由"]) --> CheckPath["判断路径是否为 /login"]
|
||||
CheckPath --> |是| NextTrue["放行"]
|
||||
CheckPath --> |否| CheckToken["读取 localStorage 中的 token"]
|
||||
CheckToken --> HasToken{"是否存在 token?"}
|
||||
HasToken --> |是| NextTrue
|
||||
HasToken --> |否| Redirect["重定向到 /login"]
|
||||
NextTrue --> SetTitle["设置页面标题"]
|
||||
Redirect --> End(["结束"])
|
||||
SetTitle --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [index.js](file://frontend/src/router/index.js#L104-L113)
|
||||
|
||||
章节来源
|
||||
- [index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
|
||||
### 状态管理(Pinia)
|
||||
- 用户 Store(user.js)
|
||||
- 状态:token、userInfo
|
||||
- 方法:登录(调用认证 API,存储 token)、获取用户信息、登出(清除 token 并跳转登录)
|
||||
- 应用 Store(app.js)
|
||||
- 状态:collapsed(侧边栏折叠状态)、departmentTree(科室树)
|
||||
- 方法:切换侧边栏、加载科室树
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class UserStore {
|
||||
+string token
|
||||
+object userInfo
|
||||
+login(username, password) Promise~boolean~
|
||||
+getUserInfo() Promise~object|null~
|
||||
+logout() void
|
||||
}
|
||||
class AppStore {
|
||||
+boolean collapsed
|
||||
+array departmentTree
|
||||
+toggleSidebar() void
|
||||
+loadDepartmentTree() Promise~void~
|
||||
}
|
||||
class API {
|
||||
+login(data) Promise
|
||||
+getCurrentUser() Promise
|
||||
+getDepartmentTree(params) Promise
|
||||
}
|
||||
UserStore --> API : "使用"
|
||||
AppStore --> API : "使用"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [user.js](file://frontend/src/stores/user.js#L6-L47)
|
||||
- [app.js](file://frontend/src/stores/app.js#L5-L30)
|
||||
- [auth.js](file://frontend/src/api/auth.js#L4-L11)
|
||||
- [department.js](file://frontend/src/api/department.js#L9-L11)
|
||||
|
||||
章节来源
|
||||
- [user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [index.js](file://frontend/src/stores/index.js#L1-L3)
|
||||
|
||||
### API 层与拦截器
|
||||
- Axios 实例:
|
||||
- baseURL:/api/v1
|
||||
- timeout:30000ms
|
||||
- Content-Type:application/json
|
||||
- 请求拦截器:自动附加 Authorization 头(Bearer token)
|
||||
- 响应拦截器:统一处理业务错误码、HTTP 状态码错误(401、403、404、500 等),并进行消息提示与路由跳转
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant View as "视图组件"
|
||||
participant Store as "Pinia Store"
|
||||
participant API as "API 模块"
|
||||
participant Axios as "Axios 实例"
|
||||
participant Interceptor as "拦截器"
|
||||
participant Backend as "后端服务"
|
||||
View->>Store : 调用 Store 方法
|
||||
Store->>API : 发起 API 请求
|
||||
API->>Axios : request.post/get(...)
|
||||
Axios->>Interceptor : 进入请求拦截器
|
||||
Interceptor->>Axios : 添加 Authorization 头
|
||||
Axios->>Backend : 发送 HTTP 请求
|
||||
Backend-->>Axios : 返回响应
|
||||
Axios->>Interceptor : 进入响应拦截器
|
||||
Interceptor->>View : 统一错误处理与业务码校验
|
||||
Interceptor-->>View : 返回数据
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [request.js](file://frontend/src/api/request.js#L6-L12)
|
||||
- [request.js](file://frontend/src/api/request.js#L14-L26)
|
||||
- [request.js](file://frontend/src/api/request.js#L28-L63)
|
||||
- [auth.js](file://frontend/src/api/auth.js#L4-L11)
|
||||
|
||||
章节来源
|
||||
- [request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
- [menu.js](file://frontend/src/api/menu.js#L1-L37)
|
||||
|
||||
### 视图组件与布局
|
||||
- 登录页(Login.vue)
|
||||
- 表单验证、加载状态、错误提示
|
||||
- 调用用户 Store 登录,成功后跳转主页面
|
||||
- 主布局(Layout.vue)
|
||||
- 侧边栏菜单:根据后端返回的菜单树渲染,支持折叠
|
||||
- 顶部导航:面包屑、用户下拉菜单、退出登录
|
||||
- 内容区域:路由视图过渡动画
|
||||
|
||||
章节来源
|
||||
- [Login.vue](file://frontend/src/views/Login.vue#L1-L155)
|
||||
- [Layout.vue](file://frontend/src/views/Layout.vue#L1-L241)
|
||||
|
||||
## 依赖关系分析
|
||||
- 入口文件依赖:main.js 依赖 App.vue、router、stores、Element Plus、全局样式
|
||||
- 路由依赖:router/index.js 依赖视图组件与菜单 API
|
||||
- 状态管理依赖:stores 依赖 API 模块
|
||||
- API 依赖:API 模块依赖 Axios 实例
|
||||
- 样式依赖:全局样式被入口文件引入
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
Main["main.js"] --> App["App.vue"]
|
||||
Main --> Router["router/index.js"]
|
||||
Main --> Stores["stores/*"]
|
||||
Main --> EP["Element Plus"]
|
||||
Main --> Styles["assets/main.scss"]
|
||||
Router --> Views["views/*"]
|
||||
Router --> MenuAPI["api/menu.js"]
|
||||
Stores --> AuthAPI["api/auth.js"]
|
||||
Stores --> DeptAPI["api/department.js"]
|
||||
Views --> AuthAPI
|
||||
Views --> MenuAPI
|
||||
Views --> DeptAPI
|
||||
AuthAPI --> Request["api/request.js"]
|
||||
MenuAPI --> Request
|
||||
DeptAPI --> Request
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
- [auth.js](file://frontend/src/api/auth.js#L1-L22)
|
||||
- [department.js](file://frontend/src/api/department.js#L1-L32)
|
||||
- [menu.js](file://frontend/src/api/menu.js#L1-L37)
|
||||
|
||||
章节来源
|
||||
- [main.js](file://frontend/src/main.js#L1-L24)
|
||||
- [index.js](file://frontend/src/router/index.js#L1-L116)
|
||||
- [app.js](file://frontend/src/stores/app.js#L1-L31)
|
||||
- [user.js](file://frontend/src/stores/user.js#L1-L49)
|
||||
- [request.js](file://frontend/src/api/request.js#L1-L66)
|
||||
|
||||
## 性能考虑
|
||||
- 代码分割与懒加载
|
||||
- 路由组件采用动态导入,按需加载,减少首屏体积
|
||||
- 图标注册
|
||||
- 通过循环注册 Element Plus 图标,避免重复注册导致的包体膨胀
|
||||
- 样式组织
|
||||
- 全局样式集中管理,避免重复定义与样式冲突
|
||||
- 构建优化
|
||||
- 使用 Vite 的原生 ES 模块与快速热更新,提升开发体验
|
||||
- 网络请求
|
||||
- Axios 统一拦截器减少重复逻辑,提高可维护性
|
||||
|
||||
章节来源
|
||||
- [index.js](file://frontend/src/router/index.js#L7-L94)
|
||||
- [main.js](file://frontend/src/main.js#L14-L17)
|
||||
- [main.scss](file://frontend/src/assets/main.scss#L1-L186)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L5-L21)
|
||||
|
||||
## 故障排除指南
|
||||
- CORS 错误
|
||||
- 现象:浏览器控制台出现跨域错误
|
||||
- 原因:开发阶段未正确配置代理或后端未允许跨域
|
||||
- 解决:确认 Vite 代理配置与后端 CORS 设置一致
|
||||
- 404 Not Found
|
||||
- 现象:请求路径返回 404
|
||||
- 原因:Vite 代理未生效或后端路由不匹配
|
||||
- 解决:重启前端开发服务器;检查后端路由与版本
|
||||
- 500 Internal Server Error
|
||||
- 现象:后端服务异常
|
||||
- 原因:后端代码错误或数据库问题
|
||||
- 解决:查看后端日志目录,定位具体错误
|
||||
- Network Error
|
||||
- 现象:无法连接后端
|
||||
- 原因:后端服务未启动
|
||||
- 解决:启动后端服务后再进行联调
|
||||
- 登录失败
|
||||
- 检查点:后端健康检查、账号密码、Content-Type
|
||||
- 清理缓存与硬刷新
|
||||
- 清空浏览器缓存、localStorage,执行硬刷新
|
||||
- 快速重启服务
|
||||
- 停止 Python 进程,重启后端与前端
|
||||
|
||||
章节来源
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L1-L119)
|
||||
- [vite.config.js](file://frontend/vite.config.js#L14-L19)
|
||||
- [request.js](file://frontend/src/api/request.js#L39-L62)
|
||||
|
||||
## 结论
|
||||
本项目通过清晰的依赖管理、合理的 Vite 配置、完善的入口与插件注册、规范的路由与状态管理、统一的 API 封装以及全局样式体系,构建了一个可扩展、易维护的 Vue 3 前端应用。配合 Element Plus 的主题与国际化配置,能够快速实现企业级界面与交互体验。建议在后续迭代中持续关注代码分割、样式复用与错误处理的细节优化。
|
||||
|
||||
## 附录
|
||||
- 开发环境搭建步骤
|
||||
- 安装依赖:使用包管理器安装项目依赖
|
||||
- 启动后端:在后端目录启动服务(参考调试指南中的命令)
|
||||
- 启动前端:在前端目录执行开发服务器命令
|
||||
- 访问应用:打开浏览器访问开发服务器地址
|
||||
- 依赖安装命令
|
||||
- 安装生产与开发依赖
|
||||
- 启动流程
|
||||
- 启动后端服务
|
||||
- 启动前端开发服务器
|
||||
- 在浏览器中打开应用并登录
|
||||
|
||||
章节来源
|
||||
- [package.json](file://frontend/package.json#L6-L10)
|
||||
- [DEBUG_GUIDE.md](file://frontend/DEBUG_GUIDE.md#L81-L95)
|
||||
Reference in New Issue
Block a user