跳到主要内容

配置指南

DynamicForm 通过 FormConfig 驱动表单。4.0 支持 fieldsgroups 和统一节点树 nodes 三种入口。配置描述字段、container、组件、初始值、校验、联动关系和 UI 行为。

平铺表单

import type { FormConfig } from '@whynotsnow/dynamic-form';

const formConfig: FormConfig = {
fields: [
{
id: 'username',
label: 'Username',
component: 'TextInput',
rules: [{ required: true, message: 'Username is required' }]
}
]
};

分组表单

const formConfig: FormConfig = {
groups: [
{
id: 'profile',
title: 'Profile',
initialVisible: true,
fields: [
{
id: 'name',
label: 'Name',
component: 'TextInput'
}
]
}
]
};

混合表单

FormConfig 可以同时包含顶层 fieldsgroupsnodes。默认 renderer 会按归一化后的根节点顺序渲染:先渲染 nodes,再渲染 fields,最后渲染由 groups 转换而来的 container。

const formConfig: FormConfig = {
fields: [{ id: 'accountType', component: 'Select' }],
groups: [
{
id: 'companyInfo',
title: '企业信息',
fields: [{ id: 'companyName', component: 'TextInput' }]
}
]
};

字段 ID 与 group ID 在整个表单内必须唯一。Group 只影响 UI 和行为作用域。字段可以通过 name 声明独立的 Ant Design NamePath,详见 Field Address

节点树

4.0 推荐在需要嵌套结构、递归布局或重复项时使用 nodes。节点树由 FieldNodeContainerNode 组成:

const formConfig: FormConfig = {
nodes: [
{
nodeType: 'container',
id: 'shipping',
title: '收货信息',
name: 'shipping',
children: [
{
nodeType: 'field',
id: 'shippingCity',
label: '城市',
component: 'TextInput'
},
{
nodeType: 'container',
id: 'shippingContact',
title: '联系人',
name: 'contact',
children: [
{
nodeType: 'field',
id: 'shippingContactName',
label: '姓名',
component: 'TextInput'
}
]
}
]
}
]
};

上例会把字段值写入 { shipping: { shippingCity, contact: { shippingContactName } } }。字段 id 仍然是 effect、Runtime 和 meta 更新使用的稳定标识;container name 只影响 Ant Design 值路径。

需要重复项时,container 可以声明 repeatable: true,并且必须声明 name

const formConfig: FormConfig = {
nodes: [
{
nodeType: 'container',
id: 'contacts',
title: '联系人',
name: 'contacts',
repeatable: true,
children: [
{
nodeType: 'field',
id: 'contactName',
label: '姓名',
component: 'TextInput'
}
]
}
]
};

Repeatable container 使用 Ant Design Form.List 渲染。当前默认渲染负责读取已有 list items;新增、删除、排序等操作应通过外层业务 UI、render hooks 或自定义容器封装提供。

字段配置

配置项说明
idRuntime、registry 和 effect graph 使用的全局唯一字段 key。
name可选 Ant Design NamePath;默认使用 id
component内置组件名或自定义注册组件名。
labelForm.Item label。
rulesAnt Design Form 校验规则。
required字段级 required 标记。
span默认 Col 渲染使用的栅格宽度。
style字段样式。
initialValue静态值,或基于已计算初始值的函数。
initialVisible初始是否可见,默认可见。
initialDisabled初始禁用意图。
preserveValueOnHide字段隐藏后是否保留当前值。
restoreValueOnShow字段重新显示后是否恢复隐藏前缓存值,默认恢复。
dependents交给 effect engine 的依赖声明。
effect依赖触发后的 effect 函数。
formItemProps静态 Form.Item props。
componentProps传给字段组件的静态 props。
designer可视化设计器专用元数据,不参与 Runtime、effect、提交或校验。

required 是字段声明属性。默认 Ant Design renderer 会把 required: true 合并成真实 Form.Item.rules,并显示 required 标记;如果 rules 中已经显式声明 required rule,则以显式 rule 为准,不重复生成。

函数式初始值

initialValue 可以是函数。函数接收已计算的初始值,可以返回原始值,也可以返回 effect result 对象。

{
id: 'fullName',
label: 'Full Name',
component: 'TextInput',
initialValue: (values) => `${values.firstName ?? ''} ${values.lastName ?? ''}`.trim()
}
{
id: 'country',
component: 'Select',
initialValue: () => ({
value: 'CN',
componentProps: {
options: [{ label: 'China', value: 'CN' }]
}
})
}

函数式初始值返回的对象会进入和运行时 effect 相同的 handler 系统。

分组配置

groups 是 4.0 之前的单层分组入口,仍然兼容。配置处理阶段会把每个 group 转换为顶层 container。

配置项说明
id分组 key。
title默认 Card 渲染使用的标题。
fields分组内字段。
initialVisible初始是否可见,默认可见。
dependents分组级依赖声明。
effect分组级 effect。
designer可视化设计器专用元数据。

分组可见性会影响子字段的渲染和提交参与。

Container 配置

配置项说明
nodeType固定为 'container'
id全局唯一 container key,也是 Runtime 和 effect graph 的稳定标识。
title默认 Card 渲染使用的标题。
name可选 Ant Design NamePath 前缀;repeatable container 必须声明。
children子节点,可以是字段或 container。
initialVisible初始是否可见,默认可见。
dependentscontainer 级依赖声明。
effectcontainer 级 effect。
repeatable是否通过 Ant Design Form.List 渲染重复项。
designer可视化设计器专用元数据。

Container 可见性会递归影响所有后代字段和子 container 的渲染、提交和校验参与。

Designer Metadata

4.1.2 起,字段、legacy group 和 container 都可以携带 designer 元数据。它只面向可视化配置系统,用来保存设计器标题、说明、分类、图标、排序、锁定状态、设计器内隐藏状态或业务自定义 metadata。

const formConfig: FormConfig = {
fields: [
{
id: 'customerName',
label: '客户名称',
component: 'TextInput',
designer: {
title: '客户名称',
category: '基础信息',
icon: 'text',
order: 10,
locked: false,
metadata: { source: 'designer' }
}
}
]
};

designer 会随配置透传和保留,但不会进入 Runtime 策略,也不会影响 effect、提交数据、校验、字段参与清理或默认 renderer 行为。设计器如果需要根据这些信息隐藏或锁定画布节点,应在可视化系统内自行消费。

配置诊断

4.1.2 新增 getFormConfigDiagnostics(config, options?)validateFormConfig(config, options?)。它们用于可视化系统保存前检查、导入配置检查和测试断言,不替代 processFormConfig();运行时配置处理仍保持原有抛错行为。

import { validateFormConfig } from '@whynotsnow/dynamic-form';

const result = validateFormConfig(formConfig, {
knownComponents: ['TextInput', 'Select']
});

if (!result.valid) {
console.log(result.diagnostics);
}

诊断覆盖重复 field/container/group id、重复 name path、repeatable container 缺少 name、空 children、未知 component、无效 group field 结构和未知 dependent。重复标识、无效结构等问题会返回 error;未知 component/dependent 更适合作为设计器提示,默认返回 warning

UI 配置

uiConfig 用于调整默认 Ant Design 外壳:

<DynamicForm
form={form}
formConfig={formConfig}
uiConfig={{
rowProps: { gutter: [16, 0] },
colProps: { span: 12 },
formProps: { layout: 'vertical' },
buttonProps: { type: 'primary' },
cardProps: { size: 'small' },
submitAreaProps: { style: { textAlign: 'right' } },
formItemProps: { colon: false }
}}
/>

默认 UI 配置包括:

  • rowProps: { gutter: [16, 0] }
  • colProps: { span: 8 }
  • 空的 form、button、card、submit area、form item props

内置组件

内置组件注册在 DefaultRegistryFieldComponents

  • Password
  • ConfirmPassword
  • TextInput
  • NumberInput
  • SelectField
  • DatePicker
  • Switch
  • Rate
  • TextDisplay
  • CheckboxGroup
  • Select
  • TextArea

SelectField 从字段配置读取 optionsSelect 通常通过 componentProps 接收 options。

values 初始数据

values prop 适用于编辑或详情回显场景。它会在 store 初始化时合并并同步到 Ant Design Form。初始化后,Ant Design Form 仍然是运行时值来源。