# BasicForm 表单 :::tip 说明 `BasicForm` 位于 `src/components/Form/src/BasicForm.vue`,基于 AntDesign Vue 的 `a-form` 二次封装,通过 schemas 配置化定义表单字段,支持查询表单和业务表单两种模式。 ::: ## 组件架构 ``` src/components/Form/ ├── src/ │ ├── BasicForm.vue # 主组件 │ ├── props.ts # 属性定义 │ ├── helper.ts # 工具函数(placeholder 生成) │ ├── types/form.ts # 类型定义(FormSchema、FormProps) │ └── hooks/ │ ├── useFormEvents.ts # 表单事件(submit、reset、validate) │ └── useFormValues.ts # 表单值处理(默认值初始化) └── index.ts # 导出 useForm、FormSchema 等 ``` ## 查询表单(列表页搜索) 列表页的搜索区域使用 `useForm` 注册表单: ```vue ``` ### querySchemas 定义 ```typescript // src/views/system/position/querySchemas.ts import { FormSchema } from '@/components/Form/index'; export const schemas: FormSchema[] = [ { field: 'name', component: 'Input', label: '岗位名称', componentProps: { placeholder: '请输入岗位名称', }, }, { field: 'status', component: 'Select', label: '状态', componentProps: { placeholder: '请选择状态', allowClear: true, options: [ { label: '正常', value: '1' }, { label: '禁用', value: '2' }, ], }, }, ]; ``` ### useForm 注册 ```typescript import { schemas } from './querySchemas'; import { useForm } from '@/components/Form/index'; const formParams = reactive({ name: '', status: '' }); const [register, {}] = useForm({ rowProps: { gutter: [16, 0] }, colProps: { xs: 24, sm: 24, md: 12, lg: 8, xl: 6, }, labelCol: { span: 6, offset: 0 }, schemas, }); function handleSubmit(values: Recordable) { handleReset(); for (const key in values) { formParams[key] = values[key]; } reloadTable(); } function handleReset() { for (const key in formParams) { formParams[key] = ''; } } ``` `useForm` 返回 `[register, formActionType]`,`register` 传给 `@register` 事件完成表单绑定。 ## 业务表单(编辑弹窗) 编辑弹窗中直接使用 `a-form` + `a-form-item` 构建表单: ```vue ``` ## BasicForm 内部渲染机制 `BasicForm.vue` 根据 `schema.component` 动态渲染对应的 AntDesign Vue 组件: ```vue ``` ## FormSchema 类型 ```typescript interface FormSchema { field: string; // 字段名 label: string; // 标签文本 component: string; // 组件类型:Input / Select / RadioGroup / Checkbox / DatePicker 等 componentProps?: any; // 组件属性(placeholder、options、allowClear 等) required?: boolean; // 是否必填 rules?: any[]; // 自定义校验规则 defaultValue?: any; // 默认值 hidden?: boolean | (({ schema, values, model }) => boolean); // 是否隐藏 slot?: string; // 自定义插槽名 suffix?: string; // 后缀插槽名 labelMessage?: string; // 标签提示信息 isFull?: boolean; // 是否全宽 type?: string; // 组件子类型 } ``` ## 表单校验 ```typescript // 手动校验 const handleSubmit = async () => { await formRef.value?.validate(); // 校验通过,提交数据 }; // 清除校验 formRef.value?.clearValidate(); ``` Schema 中的 `required: true` 会自动生成必填校验规则,也可以通过 `rules` 自定义: ```typescript { field: 'name', label: '岗位名称', component: 'Input', rules: [ { required: true, message: '请输入岗位名称', trigger: 'blur' }, { min: 1, max: 150, message: '长度在 1 到 150 个字符', trigger: 'blur' }, ], } ``` ## 表单赋值 编辑时需要将行数据赋值给表单: ```typescript const formData = reactive({ id: '', name: '', status: 1, sort: 0 }); const setFormData = async () => { const data = await getPositionDetail(props.positionId); for (const key in formData) { if (data[key] != null && data[key] != undefined) { formData[key] = data[key]; } } }; onMounted(() => { if (props.positionId) setFormData(); }); ``` :::tip 温馨提示 查询表单的字段名需要与后端 `page_like_fields` 和 `page_eq_fields` 对应,确保查询参数能正确传递到后端。`useForm` 返回的 `register` 函数传给 `@register` 事件完成表单绑定,`formActionType` 提供 `setFieldsValue`、`resetFields`、`validate` 等方法。 ::: ## 总结 BasicForm 通过 schemas 配置化定义表单字段,内部根据 `component` 动态渲染对应的 AntDesign Vue 组件。查询表单使用 `useForm` 注册并绑定 `@submit`/`@reset` 事件,业务表单直接使用 `a-form` + `reactive` 管理数据。支持多种组件类型、表单校验、数据绑定、条件隐藏等能力。