# 前端开发指南 **本文引用的文件** - [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) ## 目录 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
应用入口"] --> B["App.vue
根组件"] A --> C["router/index.js
路由配置"] A --> D["stores/*
Pinia 状态"] B --> E["views/Layout.vue
布局容器"] E --> F["views/Login.vue
登录页"] E --> G["views/Dashboard.vue
工作台"] E --> H["views/basic/Departments.vue
基础数据-科室"] E --> I["views/assessment/Assessments.vue
考核管理"] E --> J["views/reports/Reports.vue
统计报表"] A --> K["api/request.js
HTTP 封装"] K --> L["api/auth.js
认证接口"] K --> M["api/index.js
接口聚合导出"] A --> N["assets/main.scss
全局样式"] ``` 图表来源 - [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)