# 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. 异常/边界处理方案