# HealthLink-HIS 前端开发规范 > **文档类型**: 技术规范 > **适用范围**: 前端 Vue3 开发 > **版本**: v1.0 > **编制日期**: 2026-06-06 > **最后更新**: 2026-06-06 --- ## 一、技术栈 | 组件 | 版本 | 说明 | |------|------|------| | Vue | 3.x | 前端框架 | | Vite | 5.x | 构建工具 | | Element Plus | 2.x | UI组件库 | | Pinia | 2.x | 状态管理 | | Vue Router | 4.x | 路由管理 | | Axios | 1.x | HTTP客户端 | | RuoYi-Vue3 | 3.9.2+ | 基础框架 | --- ## 二、项目结构 ``` healthlink-his-ui/ ├── src/ │ ├── api/ # API接口定义 │ │ ├── module_name/ # 按模块分组 │ │ │ ├── index.js # 接口入口 │ │ │ └── *.js # 各接口文件 │ │ └── system/ # 系统管理接口 │ ├── views/ # 页面视图 │ │ └── module_name/ # 按模块分组 │ │ └── index.vue # 页面组件 │ ├── components/ # 公共组件 │ ├── store/ # Pinia状态管理 │ │ ├── modules/ # 模块store │ │ └── store.js # store入口 │ ├── router/ # 路由配置 │ ├── utils/ # 工具函数 │ ├── directive/ # 自定义指令 │ ├── plugins/ # 插件 │ ├── layout/ # 布局组件 │ └── assets/ # 静态资源 ├── vite.config.js # Vite配置 ├── package.json # 依赖配置 └── .env.dev # 开发环境变量 ``` --- ## 三、命名规范 ### 3.1 文件命名 | 类型 | 命名规则 | 示例 | |------|---------|------| | 页面组件 | `index.vue` | `views/registration/index.vue` | | 弹窗组件 | `XxxDialog.vue` | `PatientDialog.vue` | | 子组件 | `XxxDetail.vue` | `RegistrationDetail.vue` | | API文件 | `index.js` 或 `xxx.js` | `api/registration/index.js` | | Store模块 | `xxx.js` | `store/modules/user.js` | | 工具函数 | `xxx.js` | `utils/validate.js` | ### 3.2 组件命名 ```vue ``` ### 3.3 变量命名 | 类型 | 命名规则 | 示例 | |------|---------|------| | 响应式变量 | `camelCase` | `const patientList = ref([])` | | 常量 | `UPPER_SNAKE_CASE` | `const MAX_RETRY = 3` | | 事件处理函数 | `handle` 前缀 | `const handleClick = () => {}` | | 获取数据函数 | `getList` / `getData` | `const getList = async () => {}` | | 表单引用 | `xxxForm` / `ruleForm` | `const ruleForm = ref(null)` | | 表格引用 | `xxxTable` / `tableRef` | `const tableRef = ref(null)` | --- ## 四、API 接口规范 ### 4.1 API文件结构 ```javascript // api/registration/index.js import request from '@/utils/request' // 查询挂号列表 export function listRegistration(query) { return request({ url: '/healthlink-his/api/v1/registration/list', method: 'get', params: query }) } // 查询挂号详情 export function getRegistration(id) { return request({ url: '/healthlink-his/api/v1/registration/' + id, method: 'get' }) } // 新增挂号 export function addRegistration(data) { return request({ url: '/healthlink-his/api/v1/registration', method: 'post', data: data }) } // 修改挂号 export function updateRegistration(data) { return request({ url: '/healthlink-his/api/v1/registration', method: 'put', data: data }) } // 删除挂号 export function delRegistration(ids) { return request({ url: '/healthlink-his/api/v1/registration/' + ids, method: 'delete' }) } ``` ### 4.2 API 路径规范 - 统一前缀:`/healthlink-his/api/v1/` - 使用 kebab-case:`/patient-allergy` 而非 `/patientAllergy` - 列表接口:`/list` - 详情接口:`/{id}` - 新增:`POST /` - 修改:`PUT /` - 删除:`DELETE /{id}` - 批量删除:`DELETE /{ids}`(逗号分隔) --- ## 五、页面组件规范 ### 5.1 标准页面模板 ```vue ``` ### 5.2 弹窗组件模板 ```vue ``` --- ## 六、状态管理规范 (Pinia) ```javascript // store/modules/user.js import { defineStore } from 'pinia' import { login, logout, getInfo } from '@/api/login' const useUserStore = defineStore('user', { state: () => ({ token: getToken(), name: '', roles: [], permissions: [] }), actions: { async loginAction(userInfo) { const res = await login(userInfo) setToken(res.token) this.token = res.token }, async getInfoAction() { const res = await getInfo() this.name = res.user.nickName this.roles = res.roles this.permissions = res.permissions }, logoutAction() { this.token = '' this.name = '' this.roles = [] removeToken() } } }) export default useUserStore ``` --- ## 七、路由配置规范 ```javascript // router/index.js const routes = [ { path: '/registration', component: Layout, children: [ { path: '', name: 'Registration', component: () => import('@/views/registration/index.vue'), meta: { title: '挂号管理', icon: 'ticket' } } ] } ] ``` ### 路由命名规则 - 路径使用 kebab-case:`/patient-allergy` - name 使用 PascalCase:`PatientAllergy` - meta.title 使用中文:`患者过敏史` --- ## 八、样式规范 ### 8.1 使用 scoped ```vue ``` ### 8.2 使用 Element Plus 变量 ```css :deep(.el-button--primary) { --el-button-bg-color: #1890ff; } ``` ### 8.3 禁止事项 - ❌ 使用内联样式(除动态绑定外) - ❌ 使用 `!important` - ❌ 全局样式污染其他组件 --- ## 九、安全规范 ### 9.1 XSS 防护 - 用户输入使用 `v-text` 而非 `v-html` - 必须使用 `v-html` 时需做转义处理 ### 9.2 敏感信息 - 不在前端硬编码密码、密钥 - API请求通过 `request.js` 统一拦截添加Token - Token 存储在 `localStorage`,设置过期时间 ### 9.3 权限控制 - 使用 `v-hasPermi` 指令控制按钮权限 - 使用路由 `meta.roles` 控制页面权限 - 接口请求在 `request.js` 中统一处理 401/403 --- ## 十、性能优化 ### 10.1 路由懒加载 ```javascript component: () => import('@/views/registration/index.vue') ``` ### 10.2 组件按需导入 ```javascript import { ElButton, ElTable } from 'element-plus' ``` ### 10.3 大列表优化 - 超过100行使用虚拟滚动 - 列表接口必须支持分页 - 图片使用懒加载 `v-lazy` ### 10.4 内存泄漏防护 - `onMounted` 中注册的事件在 `onUnmounted` 中移除 - 定时器在组件销毁时清除 - 避免在 `watch` 中创建新对象 --- ## 十一、测试规范 ### 11.1 单元测试 (Vitest) ```javascript import { describe, it, expect } from 'vitest' import { mount } from '@vue/test-utils' import PatientDialog from './PatientDialog.vue' describe('PatientDialog', () => { it('renders correctly', () => { const wrapper = mount(PatientDialog) expect(wrapper.find('.el-dialog').exists()).toBe(true) }) }) ``` ### 11.2 E2E测试 (Playwright) ```javascript import { test, expect } from '@playwright/test' test('registration flow', async ({ page }) => { await page.goto('/login') await page.fill('#username', 'admin') await page.fill('#password', 'admin123') await page.click('.login-button') await expect(page).toHaveURL('/') await page.goto('/registration') await expect(page.locator('.el-table')).toBeVisible() }) ``` --- ## 十二、Git提交规范 同后端规范(`MD/specs/IRON_RULES.md`),额外要求: - 提交前执行 `npm run lint` 确保无报错 - 提交前执行 `npm run build:dev` 确保构建成功 --- > **文档版本**: v1.0 > **最后更新**: 2026-06-06 --- ## 七、UI设计铁律法则 > 所有前端页面设计和开发必须遵守以下法则,详见 `MD/specs/UI_DESIGN_IRON_RULES.md` ### 核心设计法则速查 | 法则 | 核心思想 | HIS应用 | |------|---------|---------| | 希克定律 | 选项越少决策越快 | 菜单≤7项,表单≤12字段 | | 费茨定律 | 目标大且近操作快 | 按钮≥44px,危险操作远离安全操作 | | 米勒定律 | 记忆负荷≤7±2 | 信息分组,Tab≤6个 | | 雅各布定律 | 遵循用户已有习惯 | 若依标准布局模式 | | 格式塔原则 | 视觉分组要清晰 | 间距系统、颜色体系 | | 多赫蒂阈值 | 响应<400ms | loading态、骨架屏、分页 | | 尼尔森十大原则 | 全面可用性 | 操作反馈、防错、容错 | | 泰斯勒定律 | 复杂性守恒 | 智能默认值、常用模板 | | 峰终定律 | 关键时刻做好 | 成功动画、错误优雅处理 | | 冯·雷斯托夫 | 不同的更容易记住 | 危急值红色脉冲、徽标通知 | ### 设计文档必备 每个新页面/模块的设计文档必须包含: 1. 页面UI布局描述(组件位置、栅格、比例) 2. 交互效果清单(每个操作→效果→反馈) 3. 前后端调用流程(操作→API→处理链→渲染) 4. 状态流转图 5. 异常/边界处理方案