Skip to content

DynamicForm 动态表单

动态表单组件,用于快速构建基于配置的表单界面。

TIP

除了完整的动态表单组件,我们也提供了独立的 EzFormItem 组件,可以用于构建自定义表单布局。

组件概述

DynamicForm 用于把常见表单页面抽象成“配置驱动”的方式构建。相比手写大量 el-form-item,它更适合字段较多、结构相对规则、需要快速迭代的业务表单场景。

它当前主要解决这几类问题:

  • 通过 items 快速声明单分组表单,适合作为简单场景下的快捷写法。
  • 通过 groups 把表单拆成多个正式分组,支持标题、描述、分组级布局和分组插槽。
  • 内置常见表单组件类型、必填规则、显隐联动、禁用联动,减少重复样板代码。
  • 同时保留字段级插槽和分组级插槽,便于在标准化配置和高度定制化之间切换。

推荐使用原则:

  • groups 是标准模式,适合作为长期维护的正式配置模型。
  • items 是单分组场景的 shorthand,适合简单表单或临时查询区。
  • 如果某一块布局已经明显超出“配置生成”的边界,可以结合 EzFormItem 或分组插槽单独定制。
  • 使用 cols 做栅格布局时,不建议再传 inlineel-form,否则容易和栅格分栏产生布局冲突。

基础用法

组件类型

表单校验

自定义插槽

分组表单

字段序列化

属性

属性名说明类型是否必须默认值
v-model表单双向绑定数据Record{}
items单分组场景的简写配置FormItemConfig[][]
groups标准分组配置(推荐)FormGroupConfig[][]
cols栅格布局列数number1
gutter栅格间距number20
其他 Form 属性通过组件属性透传给 el-formPartial<Omit<FormProps, 'model' | 'rules' | 'showMessage'>>-

FormItemConfig

属性名说明类型是否必须默认值
prop字段名string-
label标签string-
type组件类型。内建分支仅接受 FormItemType 字面量;自定义组件场景使用 component 即可FormItemType-
defaultValue默认值any-
rules验证规则FormItemRule-
required是否必填booleanfalse
requiredMessage必填提示信息string-
span占用栅格列数number-
hidden是否隐藏booleanfalse
disabled是否禁用booleanfalse
placeholder占位符string-
options选项配置。select 支持分组选项,radio/checkbox 使用各自选项类型,tree-select/cascader 按结构化数据源透传FormItemOption[]-
attrs组件属性(透传给具体组件)。select/radio/checkbox/upload-images、tree-select、cascader 会按各自公开字段子集提供更明确的类型提示,其他内建控件保持宽透传Record-
component自定义字段组件。需要遵循 modelValue / update:modelValue / disabled 契约Component-
itemAttrs额外的 el-form-item 属性Partial<FormItemProps>-
show联动显示条件Function-
disabledWhen联动禁用条件Function-
serialize提交前字段序列化Function-
deserialize外部数据回填时的字段反序列化Function-

FormGroupConfig

属性名说明类型是否必须默认值
name分组唯一标识string-
title分组标题string-
description分组描述string-
items分组下的表单项FormItemConfig[][]
cols分组内栅格列数number继承全局 cols
gutter分组内栅格间距number继承全局 gutter
hidden是否隐藏分组booleanfalse
show分组联动显示条件Function-
className分组容器 classstring-
style分组容器 stylestring | Record-
headerClassName分组头部 classstring-
headerStyle分组头部 stylestring | Record-
bodyClassName分组主体 classstring-
bodyStyle分组主体 stylestring | Record-
headerSlot自定义分组头插槽名stringgroup-header-${name}
slot自定义分组内容插槽名stringgroup-${name}

数据初始化与双向绑定

  • v-model:通过 v-model 进行双向绑定,表单项的修改会实时同步到外部。
  • defaultValue:配置项的默认值,仅在绑定的 model 对象中不存在该字段时,会在初始化时自动补全。
  • items / groups 互斥itemsgroups 不能同时传入,组件会直接报错。
  • 模式定位groups 是正式配置模型;items 只是单分组快捷写法,不再扩展分组级能力。
  • 类型约束FormItemConfig 现在会针对 selectradiocheckboxtree-selectcascaderupload-imagescomponent 这些分支提供更明确的 attrs/options 约束;其中 tree-selectcascader 也收敛到了稳定的 attrs 子集。
  • 自定义组件契约component 分支不再是“任意组件都可以”,而是默认要求满足字段组件协议。

数据流设计

本组件支持 Vue 3 标准的 v-model 双向绑定:

  • 推荐使用 v-model 驱动数据,确保表单与业务逻辑数据实时同步。
  • 使用 getFormData() 获取当前表单数据的副本(深拷贝)。
  • 使用 getSubmitData() 获取应用字段级 serialize 后的提交数据。
  • 使用 setFormData() 显式合并或替换数据。
  • 使用 setSubmitData() 将提交态数据反序列化后回填到表单模型。未声明为表单 prop 的额外提交字段不会写入 v-model
  • 使用 captureInitialData() 记录当前表单状态为新的重置基线。
  • 使用 resetForm() 将表单恢复到当前基线数据。

提示

  • 组件内部会通过 ensureStateStructure 自动补全 itemsgroups 中定义的 prop 键,以确保 Element Plus 的校验追踪能正常工作。
  • 即使 v-model 绑定的是一个空的 reactiveref 对象,组件也会在挂载或外部替换数据后根据配置自动初始化结构。
  • setFormData() 在合并或替换数据后会自动补齐缺失字段,并清空当前校验状态。
  • getSubmitData() 不会修改当前 v-model,它只返回应用字段级 serialize 后的新对象。
  • setSubmitData() 只会回填已声明的表单字段,因此诸如拆分后的日期字段这类请求态字段可以留在 UI 模型之外。
  • 组件会在首次挂载完成后自动记录一份初始化快照,resetForm() 默认恢复到这份快照。

FormItemType

名称说明
INPUT输入框
TEXTAREA多行文本
NUMBER数字输入
PASSWORD密码输入
SELECT下拉选择(封装组件)
RADIO单选框(封装组件)
CHECKBOX多选框(封装组件)
DATE日期选择
DATETIME日期时间
DATERANGE日期范围
DATETIMERANGE日期时间范围
TIME时间选择
TIMERANGE时间范围
UPLOAD_IMAGES图片上传(封装组件)
SWITCH开关
TREE_SELECT树形选择
CASCADER级联选择
SLIDER滑块
RATE评分

方法

方法名说明类型
validate验证表单Function
validateField验证指定字段Function
clearValidate清空验证Function
getFormData获取表单数据(按需调用)Function
getSubmitData获取应用字段序列化后的提交数据Function
setFormData设置表单数据(会清除校验,支持合并或完全替换)Function
setSubmitData设置提交态数据并反序列化回填Function
resetForm重置表单到当前基线数据Function
captureInitialData将当前表单状态记录为新的基线Function

插槽

插槽名说明参数
[prop]自定义表单项内容{ item: FormItemConfig, value: any, formData: Record }
label-[prop]自定义表单项标签{ item: FormItemConfig }
group-header通用分组头插槽{ group: FormGroupConfig, index: number, items: FormItemConfig[], formData: Record }
group通用分组内容插槽{ group: FormGroupConfig, index: number, items: FormItemConfig[], formData: Record }
group-header-[name]指定分组头插槽{ group: FormGroupConfig, index: number, items: FormItemConfig[], formData: Record }
group-[name]指定分组内容插槽{ group: FormGroupConfig, index: number, items: FormItemConfig[], formData: Record }

基于 MIT 许可发布