Files
hospital_performance/.qoder/repowiki/zh/content/前端开发指南/Vue组件开发/Vue Composition API开发.md
2026-02-28 15:16:15 +08:00

16 KiB
Raw Blame History

Vue Composition API开发

**本文引用的文件** - [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)

目录

  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 汇聚接口模块。

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/>代理/别名"]

图表来源

章节来源

核心组件

  • 应用入口与插件注册:在 main.js 中创建应用、注册 Element Plus、Pinia、路由并挂载到 DOM。
  • 根组件 App.vue提供语言环境配置承载路由视图。
  • 路由与守卫router/index.js 定义多级菜单路由与登录守卫。
  • 全局状态stores/app.js 与 stores/user.js 使用组合式 StoredefineStore 返回函数式 Store内部使用 ref 管理响应式状态。
  • 页面组件views 下包含 Dashboard、Layout、Assessments、Departments 等,广泛使用 setup 函数、ref、reactive、computed、watch/watchEffect、生命周期钩子与 API 调用。

章节来源

架构总览

下图展示从入口到页面组件的数据与控制流main.js 初始化应用与插件App.vue 渲染路由视图Layout.vue 作为布局容器,调用 stores 与 API具体业务页面如 Dashboard、Assessments、Departments在 setup 中声明响应式数据、计算属性、监听器与生命周期钩子,并发起 API 请求。

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 : 渲染视图

图表来源

详细组件分析

setup 函数与响应式数据ref vs reactive

  • 在页面组件中setup 函数用于声明响应式数据与逻辑。常见模式:
    • 使用 ref 声明基本类型或简单对象如字符串、数字、布尔值、DOM 引用等。
    • 使用 reactive 声明复杂对象(如表单、分页参数),便于在模板中直接访问其属性。
  • 示例组件中的使用:
    • Dashboard.vue大量使用 ref如图表容器引用、周期选择、统计数据对象与 reactive如搜索条件、分页参数
    • Assessments.vue同时使用 refloading、对话框可见性与 reactive搜索表单、分页、批量创建表单
    • Departments.vue同样混合使用 ref 与 reactive。
  • 设计建议:
    • 对于简单标量或需要重新赋值的对象,优先使用 ref。
    • 对于复杂对象且不需要整体替换,优先使用 reactive。
    • 在模板中频繁访问深层属性时reactive 更直观需要整体替换或跨函数传递引用时ref 更合适。

章节来源

计算属性 computed

  • computed 用于派生状态,自动追踪依赖并在依赖变化时重新计算。
  • 示例:
    • Dashboard.vue 中的 assessedRate完成率与 hasAlerts是否存在预警均通过 computed 声明,避免在模板中重复计算。
  • 最佳实践:
    • 仅依赖响应式数据;避免在 getter 内部修改状态。
    • 复杂计算尽量拆分为多个小的 computed提升可维护性。

章节来源

监听器 watch 与 watchEffect

  • watch监听特定响应式数据的变化适合需要在变化时执行副作用如发起请求、更新图表
    • 示例Dashboard.vue 中对周期选择chartPeriod、financePeriod、rankingPeriod的监听触发对应数据加载与图表更新。
  • watchEffect自动追踪其执行期间访问到的响应式数据无需显式声明监听目标。
    • 示例Dashboard.vue 中在加载关键指标后使用 nextTick再更新仪表盘图表体现了 watchEffect 的自动依赖追踪特性。
  • 最佳实践:
    • watch 适用于明确的目标与旧值/新值对比watchEffect 适用于“只要相关数据变化就刷新”的场景。
    • 注意清理副作用(如在组件卸载时取消订阅或清空定时器)。

章节来源

生命周期钩子onMounted、onUnmounted 等

  • onMounted在组件挂载后执行初始化逻辑如加载菜单、初始化图表、绑定窗口 resize 事件等。
    • Layout.vue在 onMounted 中加载菜单树。
    • Dashboard.vue在 onMounted 中初始化多个 ECharts 实例并绑定 resize 事件。
  • onUnmounted用于清理副作用如移除事件监听、销毁图表实例
    • Dashboard.vue在组件卸载时应移除 window.resize 监听与图表实例,避免内存泄漏。
  • 最佳实践:
    • 将副作用集中在 onMounted 中启动,在 onUnmounted 中统一清理。
    • 对于需要等待 DOM 更新后再执行的逻辑,配合 nextTick 使用。

章节来源

组合函数Composables设计与复用

  • 当前项目中,全局状态通过 Pinia 的组合式 Store函数式 Store实现内部使用 ref 管理状态,对外暴露方法与状态。
    • app.js封装侧边栏折叠状态与科室树加载。
    • user.js封装登录、登出、用户信息获取。
  • 设计模式建议:
    • 将可复用的逻辑(如图表初始化、分页加载、表单校验)抽象为独立的 Composable返回 ref 或 reactive 数据与方法。
    • 在组件中通过 import 使用这些 Composable保持 setup 的简洁与关注点分离。
  • 状态共享:
    • 使用 Pinia Store 在组件间共享状态;对于轻量状态,也可通过 props/$emit 或 provide/inject 实现。

章节来源

从 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

章节来源

组件重构示例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结合进一步提升复用性。

章节来源

依赖分析

  • 依赖关系概览:
    • 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 等。
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/*"]

图表来源

章节来源

性能考虑

  • 图表渲染性能:
    • 在 Dashboard 中,多个 ECharts 实例在 onMounted 中初始化,应在 onUnmounted 中销毁实例并移除 resize 监听,避免内存泄漏。
    • 对于大数据量图表,建议在 watch 中按需更新选项,避免全量 setOption 导致重绘开销。
  • 状态更新与重渲染:
    • 使用 computed 缓存派生结果,减少不必要的重渲染。
    • 将复杂计算拆分为多个小的 computed降低依赖范围。
  • API 请求节流:
    • 对于高频变更(如日期选择、筛选条件),可在 watch 中加入防抖策略,减少请求次数。
  • 路由懒加载:
    • 路由组件已使用动态导入,有助于首屏加载性能。

故障排查指南

  • 登录与路由守卫:
    • 若进入受保护页面被重定向到登录页,检查本地存储 token 是否存在;路由守卫会根据 token 决定是否放行。
  • 图表不显示或空白:
    • 确认 onMounted 中已初始化图表实例并在数据就绪后 setOption若使用 nextTick请确保在数据更新后再执行更新逻辑。
  • 菜单加载失败:
    • Layout.vue 中的菜单加载失败会回退到默认菜单;检查后端接口与网络请求状态。
  • 状态不同步:
    • Pinia Store 中的状态更新需通过 ref.value 修改;确保在组件中正确读取与写入。

章节来源

结论

本项目已全面采用 Vue 3 Composition API结合 Pinia 实现状态管理,配合 Element Plus 与 ECharts 构建了功能完备的绩效管理系统前端。通过在 setup 中集中声明响应式数据、计算属性、监听器与生命周期钩子提升了代码的可读性与可维护性。建议在后续开发中持续引入组合函数Composable以增强逻辑复用并在图表与数据密集场景中优化渲染与请求策略进一步提升用户体验与性能表现。

附录

  • 开发与构建命令:
    • dev启动开发服务器
    • build打包生产资源
    • preview预览生产构建
  • 代理配置:
    • 前端开发时将 /api 代理到后端服务地址,便于联调。

章节来源