# 前端页面视图 前端页面视图是用户直接交互的界面。项目使用 Vue3 + Ant Design Vue + Vite 构建。一个完整的 CRUD 页面由 5 个文件组成: ``` ui/src/views/tool/example/ ├── index.vue # 主页面:搜索 + 表格 + 操作 ├── edit.vue # 编辑弹窗:新增/编辑表单 ├── detail.vue # 详情弹窗:查看记录详情 ├── columns.ts # 表格列定义 └── querySchemas.ts # 搜索表单 Schema ``` ## 1. 主页面 index.vue 主页面是模块的入口页面,包含搜索表单、数据表格和操作按钮。 ### 核心结构 ```vue ``` ### 核心逻辑 ```vue ``` ### 关键点 - **PageWrapper**:页面容器,提供统一的页面布局 - **BasicForm**:搜索表单组件,通过 `useForm` 注册 - **BasicTable**:数据表格组件,内置分页功能 - **bodyCell 插槽**:操作列通过 `bodyCell` 插槽 + `v-perm` 指令实现权限控制 - **defineAsyncComponent**:懒加载弹窗组件,优化首屏加载 - **Modal.confirm**:Ant Design Vue 的确认弹窗 - **v-perm**:权限指令,控制按钮显示 ## 2. 编辑弹窗 edit.vue 编辑弹窗是独立组件,负责新增和编辑操作的表单展示与提交。 ### 核心结构 ```vue ``` ### 核心逻辑 ```vue ``` ### 关键点 - **Props 接收**:`visible` 控制弹窗显示,`id` 区分新增/编辑模式 - **新增/编辑判断**:`props.id ? exampleUpdate : exampleAdd` - **防重复提交**:`useLockFn` 包装提交函数,点击后按钮变为 loading 状态 - **数据回填**:编辑模式下调用 `getExampleDetail` 获取数据并填充表单 - **事件通信**:`emit('update:visible')` 关闭弹窗,`emit('success')` 通知刷新 ## 3. 详情弹窗 detail.vue 详情弹窗用于展示记录的详细信息,使用 Ant Design Vue 的 `a-descriptions` 组件。 ### 核心结构 ```vue ``` ### 关键点 - **a-descriptions**:Ant Design Vue 的描述列表组件,用于展示详情 - **getChoiceLabel**:将枚举值转换为中文标签 - **图片预览**:使用 `a-image` 实现图片预览 ## 4. 表格列定义 columns.ts 定义表格的列配置,包括列名、字段名、宽度和自定义渲染。 ### 完整代码 ```typescript import { h } from 'vue'; import { Tag, Image } from 'ant-design-vue'; export const columns = [ { title: 'ID', dataIndex: 'id', fixed: 'left', width: 50, }, { title: '案例名称', dataIndex: 'name', width: 150, }, { title: '案例图片', dataIndex: 'avatar', width: 150, customRender({ record }) { return record.avatar ? h(Image, { src: record.avatar, width: 48, height: 48, fit: 'cover', preview: true }) : h('span', '-'); }, }, { title: '案例类型', dataIndex: 'type', width: 100, customRender({ record }) { const statusMap = { 1: { text: '类型1', color: 'success' }, 2: { text: '类型2', color: 'error' }, 3: { text: '类型3', color: 'warning' }, 4: { text: '类型4', color: 'default' }, }; const status = statusMap[record.type]; return h(Tag, { color: status?.color || 'default' }, { default: () => status?.text || record.type }); }, }, { title: '案例状态', dataIndex: 'status', width: 100, customRender({ record }) { const statusMap = { 1: { text: '正常', color: 'success' }, 2: { text: '禁用', color: 'error' }, }; const status = statusMap[record.status]; return h(Tag, { color: status?.color || 'default' }, { default: () => status?.text || record.status }); }, }, { title: '排序', dataIndex: 'sort', width: 100, }, { title: '创建人', dataIndex: 'createUser', width: 100, }, { title: '创建时间', dataIndex: 'createTime', width: 180, }, { title: '操作', fixed: 'right', dataIndex: 'action', key: 'action', width: 200, }, ]; ``` ### 关键点 - **title / dataIndex**:Ant Design Vue 的列定义字段 - **customRender 函数**:使用 Vue 的 `h()` 函数创建虚拟 DOM - **Tag 组件**:将状态值渲染为彩色标签(`color: 'success'` / `'error'`) - **Image 组件**:将图片 URL 渲染为缩略图 ## 5. 搜索表单 querySchemas.ts 定义搜索表单的字段配置,使用项目封装的 `FormSchema` 类型。 ### 完整代码 ```typescript import { FormSchema } from '@/components/Form/index'; export const schemas: FormSchema[] = [ { name: 'name', component: 'Input', label: '案例名称', componentProps: { placeholder: '请输入案例名称', clearable: true, allowClear: true }, }, { name: 'type', component: 'Select', label: '案例类型', componentProps: { placeholder: '请输入案例类型', clearable: true, allowClear: true, options: [ { label: '类型1', value: 1 }, { label: '类型2', value: 2 }, { label: '类型3', value: 3 }, { label: '类型4', value: 4 }, ], }, }, { name: 'status', component: 'Select', label: '案例状态', componentProps: { placeholder: '请输入案例状态', clearable: true, allowClear: true, options: [ { label: '正常', value: 1 }, { label: '禁用', value: 2 }, ], }, }, ]; ``` ### 关键点 - **name**:字段名,与后端查询参数对应 - **component**:表单组件类型:`Input` / `Select` / `DatePicker` 等 - **componentProps**:组件属性,透传给 Ant Design Vue 组件 - **allowClear**:Ant Design Vue 的清除属性 - **options**:Select 组件的下拉选项 ## 文件关系图 ``` index.vue(主页面) ├── import schemas from './querySchemas' ← 搜索表单配置 ├── import columns from './columns' ← 表格列配置 ├── import editDialog from './edit.vue' ← 编辑弹窗组件 ├── import detailDialog from './detail.vue' ← 详情弹窗组件 └── import API from '@/api/tool/example' ← 接口请求 edit.vue(编辑弹窗) └── import API from '@/api/tool/example' ← 接口请求 detail.vue(详情弹窗) └── import API from '@/api/tool/example' ← 接口请求 ``` ## 开发要点 1. **一个模块一个目录**:放在 `ui/src/views/{group}/{module}/` 下 2. **5 个文件各司其职**:主页面、编辑弹窗、详情弹窗、列定义、搜索 Schema 3. **弹窗是独立组件**:通过 Props 接收 ID,通过 Emit 通知父页面 4. **列定义使用 `h()` 渲染复杂内容**:如状态标签、图片缩略图 5. **搜索 Schema 使用 `FormSchema` 类型**:配置化定义表单字段 6. **新增/编辑通过 `id` 区分**:0 为新增,非 0 为编辑 7. **防重复提交使用 `useLockFn`**:提交时按钮 loading 8. **操作列使用 `bodyCell` 插槽**:通过插槽自定义操作按钮 9. **确认弹窗使用 `Modal.confirm`**:Ant Design Vue 的确认弹窗 10. **消息提示使用 `message.success()`**:Ant Design Vue 的消息提示 ## 总结 前端页面统一使用 `PageWrapper` + `BasicForm` + `BasicTable` + `bodyCell` 插槽四件套,分页由 `BasicTable` 内置处理。每个模块包含 `index.vue`(列表页)、`edit.vue`(编辑弹窗)、`detail.vue`(详情弹窗)、`columns.ts`(列定义)、`querySchemas.ts`(搜索配置)五个文件。