# 前端开发文档 本文档定义了项目的开发规范、组件复用指南和代码风格要求,确保团队开发风格统一。 --- ## 一、开发规范 ### 1.1 组件开发规范 #### 组件命名 ```typescript // ✅ 正确:组件文件使用 PascalCase UserList.vue DictTag.vue TableAction.vue // ❌ 错误:使用 kebab-case 或其他命名 user-list.vue dict_tag.vue ``` #### 组件定义 ```vue ``` #### TypeScript 规范 ```typescript // ✅ 正确:禁止使用 any,使用具体类型 interface UserInfo { id: number; name: string; email?: string; } function getUser(id: number): Promise { return request.get(`/user/${id}`); } // ❌ 错误:使用 any function getUser(id: any): any { return request.get(`/user/${id}`); } // ✅ 正确:使用 import type 导入类型 import type { UserInfo } from '#/api/system/user'; // ❌ 错误:普通导入类型 import { UserInfo } from '#/api/system/user'; ``` ### 1.2 目录结构规范 ``` src/ ├── api/ # API 接口定义,按模块划分 │ ├── system/ # 系统模块 │ │ ├── user/ │ │ │ └── index.ts │ │ └── dept/ │ │ └── index.ts │ └── ... ├── components/ # 公共组件(全局注册) ├── views/ # 页面组件,按业务模块划分 │ └── system/ │ └── user/ │ ├── index.vue # 列表页 │ ├── data.ts # 数据定义 │ └── modules/ # 子组件/弹窗 │ └── form.vue ├── locales/ # 国际化 ├── router/ # 路由配置 ├── stores/ # Pinia 状态管理 ├── utils/ # 工具函数 └── adapter/ # 适配器配置 ``` ### 1.3 API 接口规范 ```typescript // src/api/system/user/index.ts import { request } from '#/utils/request'; export namespace SystemUserApi { /** 用户信息 */ export interface User { id: number; username: string; nickname: string; email?: string; status: number; deptId?: number; createTime: string; } /** 用户分页查询参数 */ export interface PageParams { pageNo: number; pageSize: number; username?: string; status?: number; deptId?: number; } /** 分页结果 */ export interface PageResult { list: User[]; total: number; } } /** 获取用户分页列表 */ export function getUserPage(params: SystemUserApi.PageParams) { return request.get('/system/user/page', { params }); } /** 获取用户详情 */ export function getUser(id: number) { return request.get(`/system/user/get?id=${id}`); } /** 创建用户 */ export function createUser(data: SystemUserApi.User) { return request.post('/system/user/create', data); } /** 更新用户 */ export function updateUser(data: SystemUserApi.User) { return request.put('/system/user/update', data); } /** 删除用户 */ export function deleteUser(id: number) { return request.delete(`/system/user/delete?id=${id}`); } ``` ### 1.4 样式规范 ```vue ``` --- ## 二、核心组件复用指南 ### 2.1 表格组件 (useVbenVxeGrid) 项目使用 VxeTable 封装的 `useVbenVxeGrid` 作为核心表格组件。 #### 基础用法 ```vue ``` #### 表格列渲染器 | 渲染器 | 用途 | 示例 | |--------|------|------| | `CellImage` | 单图展示 | `cellRender: { name: 'CellImage' }` | | `CellImages` | 多图展示 | `cellRender: { name: 'CellImages' }` | | `CellLink` | 链接按钮 | `cellRender: { name: 'CellLink', props: { text: '查看' } }` | | `CellTag` | 标签展示 | `cellRender: { name: 'CellTag', props: { color: 'blue' } }` | | `CellDict` | 字典标签 | `cellRender: { name: 'CellDict', props: { type: 'common_status' } }` | | `CellSwitch` | 开关切换 | `cellRender: { name: 'CellSwitch', attrs: { beforeChange } }` | | `CellOperation` | 操作按钮 | `cellRender: { name: 'CellOperation', options: ['edit', 'delete'] }` | ### 2.2 表单弹窗 (useVbenModal) ```vue ``` 表单组件示例: ```vue ``` ### 2.3 字典组件 #### DictTag - 字典标签 用于展示数据字典值的标签形式。 ```vue ``` #### DictSelect - 字典选择器 用于表单中从字典选择值。 ```vue ``` #### 字典工具函数 ```typescript import { getDictOptions, getDictLabel, getDictObj } from '#/packages/effects/hooks/src'; // 获取字典选项列表(用于 Select/Radio 等组件) const options = getDictOptions('common_status', 'number'); // 获取字典标签文本 const label = getDictLabel('common_status', 1); // "开启" // 获取字典完整对象 const dictObj = getDictObj('common_status', 1); // { label: '开启', value: 1, colorType: 'success', cssClass: '' } ``` ### 2.4 表格操作组件 (TableAction) 用于表格中的操作按钮,支持权限控制和二次确认。 ```vue ``` ### 2.5 文件上传组件 #### ImageUpload - 图片上传 ```vue ``` #### FileUpload - 文件上传 ```vue ``` ### 2.6 描述列表组件 (Description) 用于详情页展示数据。 ```vue ``` --- ## 三、状态管理 ### 3.1 使用 Pinia Store 项目使用 Pinia 进行状态管理,Store 定义在 `src/packages/stores/src` 中。 #### 常用 Store | Store | 用途 | 导入路径 | |-------|------|----------| | `useUserStore` | 用户信息 | `#/packages/stores/src` | | `useAccessStore` | 权限/Token | `#/packages/stores/src` | | `useDictStore` | 数据字典 | `#/packages/stores/src` | #### 示例 ```typescript import { useUserStore, useAccessStore } from '#/packages/stores/src'; const userStore = useUserStore(); const accessStore = useAccessStore(); // 获取用户信息 const userInfo = userStore.userInfo; // 检查权限 const { hasAccessByCodes } = useAccess(); const canEdit = hasAccessByCodes(['system:user:update']); ``` --- ## 四、权限控制 ### 4.1 按钮权限 ```vue ``` ### 4.2 路由权限 在路由配置中通过 `meta.authorities` 设置权限: ```typescript { path: 'user', name: 'SystemUser', component: () => import('#/views/system/user/index.vue'), meta: { title: '用户管理', authorities: ['system:user:visit'], }, } ``` --- ## 五、国际化 ### 5.1 使用方式 ```vue ``` ### 5.2 添加国际化文本 在 `src/locales` 目录下的语言文件中添加: ```json // src/locales/zh-CN.json { "common": { "save": "保存", "cancel": "取消" }, "ui": { "actionMessage": { "deleteSuccess": "删除【{0}】成功" } } } ``` --- ## 六、常用 Hooks ### 6.1 usePagination - 分页 ```typescript import { usePagination } from '#/packages/effects/hooks/src'; const { page, pageSize, total, setPage, setTotal } = usePagination(); ``` ### 6.2 useTabs - 标签页操作 ```typescript import { useTabs } from '#/packages/effects/hooks/src'; const { closeOtherTabs, closeTab, refreshTab } = useTabs(); // 关闭其他标签页 await closeOtherTabs(); // 刷新当前页 await refreshTab(); ``` ### 6.3 useWatermark - 水印 ```typescript import { useWatermark } from '#/packages/effects/hooks/src'; const { updateWatermark, destroyWatermark } = useWatermark(); // 设置水印 await updateWatermark({ content: '用户名', }); // 销毁水印 destroyWatermark(); ``` --- ## 七、工具函数 ### 7.1 常用工具 ```typescript import { formatDateTime, // 日期格式化 formatDate, // 日期格式化(不含时间) downloadFileFromBlobPart, // 文件下载 isEmpty, // 判空 isFunction, // 判断函数 isString, // 判断字符串 } from '#/packages/utils/src'; // 日期格式化 formatDateTime('2024-01-01T12:00:00'); // "2024-01-01 12:00:00" // 文件下载 downloadFileFromBlobPart({ fileName: '用户列表.xlsx', source: blobData, }); // 判空 isEmpty([]); // true isEmpty({}); // true isEmpty(null); // true ``` ### 7.2 数字格式化 ```typescript import { erpNumberFormatter, // 数字格式化 fenToYuan, // 分转元 formatFileSize, // 文件大小格式化 } from '#/packages/utils/src'; // 保留两位小数 erpNumberFormatter(1234.567, 2); // "1,234.57" // 分转元 fenToYuan(12345); // 123.45 // 文件大小 formatFileSize(1024 * 1024); // "1.00 MB" ``` --- ## 八、代码示例:标准 CRUD 页面 ```vue ``` --- ## 九、注意事项 1. **路径别名**:`#/*` 指向 `./src/*`,导入时使用 `#/components/xxx` 而非相对路径 2. **表单验证**:使用 VeeValidate + Zod,在 schema 中通过 `rules` 属性定义 3. **HTML 安全**:用户输入的 HTML 使用 `v-dompurify-html` 处理 4. **敏感数据**:使用 `secure-ls` 加密存储 5. **代码注释**:只在 WHY 不明显时添加注释,避免无意义的注释 6. **组件命名**:必须使用 `defineOptions({ name: 'ComponentName' })` 定义组件名 --- ## 十、相关资源 - [Vue 3 文档](https://vuejs.org/) - [Ant Design Vue 文档](https://antdv.com/) - [VxeTable 文档](https://vxetable.cn/) - [Tailwind CSS 文档](https://tailwindcss.com/) - [项目 CLAUDE.md](./CLAUDE.md)