字段不多时,让表单自动渲染就足够了。可当表单逐渐包含基本资料、联系方式、业务记录时,我们还会关心:字段怎样分组?哪些字段应该并排?哪些内容应该放进独立页签?
Cabloy 的 Form Layout 就是为这件事准备的。它允许我们在 DTO 中描述多个字段在表单中的位置和层级,前端再按照这份配置展示布局。
简单来说:Form Layout 负责"字段放在哪里";字段类型、校验规则等仍由原有的 schema 和表单配置负责。
Form Layout 能做什么
通过 Form Layout,可以在 DTO 中完成这些常见需求:
- 调整字段显示顺序;
- 将相关字段放进一个有标题的业务分组;
- 在桌面端使用多列,在手机上自动改为单列;
- 将"基本信息""培训记录"这类独立内容拆到不同 Tab;
- 让 Create、Update、View 等表单场景采用一致的结构思路。
它常用的几个节点并不复杂:
field:放置一个字段;section:把字段排成一列或多列;group:把一组相关字段组织在一起;tabs/tab:把不同业务内容分到标签页中。
例子:组织 Student 表单
下面截取自 Student Create DTO 中与 Form Layout 有关的部分。为了突出布局,省略了 DTO 外层定义、页面操作和其他字段配置。
tsx
ZovaRender.block('basic-form:blockFormLayout', {
formLayout: {
children: [
{
type: 'tabs',
children: [
{
type: 'tab',
title: $locale('BasicInformation'),
children: [
{
type: 'group',
title: $locale('StudentProfile'),
children: [
{
type: 'section',
columns: { default: 1, md: 2 },
children: [
{ type: 'field', name: 'name' },
{ type: 'field', name: 'mobile' },
{
type: 'field',
name: 'imageId',
span: { default: 1, md: 2 },
},
],
},
],
},
],
},
{
type: 'tab',
title: $locale('TrainingRecords'),
children: [
{ type: 'field', name: 'level' },
{ type: 'field', name: 'trainingRecords' },
],
},
],
},
],
},
});
把这段代码从外到内读,就很容易理解它最终要呈现什么。
1. tabs 和 tab:按业务内容拆分页面
最外层的 tabs 创建一组标签页。这里有两个 tab:
BasicInformation:基本信息;TrainingRecords:培训记录。
如果一张表单里有多个彼此独立的业务区域,Tab 能帮助读者一次只关注当前内容。字段较少时则不必强行使用 Tab,直接分组通常更直观。
2. group:给相关字段一个明确的归属
基本信息页签中的 group 标题是 StudentProfile。它把姓名、手机号和头像放在"学员资料"这个共同语义下。
可以把 group 理解成一个带标题的业务分组。联系方式、收货地址、审批信息等,也都是适合使用 Group 的场景。
3. section:控制响应式分栏
columns: { default: 1, md: 2 } 表示默认一列,到 md 及以上宽度时改为两列。因此,name 与 mobile 可以在桌面端并排显示,在手机上自然变成上下排列。
4. field:引用 DTO 中已经定义的字段
每个 field 通过 name 对应 DTO schema 中的字段,例如 name。它的输入控件、标题和校验规则仍沿用字段本身已有的定义。
imageId 的 span: { default: 1, md: 2 } 表示它在默认一列时占一列,在两列布局中横跨两列,适合头像、备注、说明等希望独占一行的字段。
怎么选择节点
第一次配置 Form Layout 时,可以从最小结构开始:
| 需求 | 建议使用 |
|---|---|
| 只想调整字段顺序 | field |
| 希望字段在宽屏并排显示 | section |
| 希望相关字段有共同标题和边界 | group |
| 希望拆分真正独立的业务内容 | tabs / tab |
一个常见组合是:Tab 划分业务区域,Group 表达业务分组,Section 处理响应式分栏,Field 放置具体字段。
但不需要为了层级"完整"而把每个容器都套上。简单表单只用 field;需要两列时加 section;字段确实属于同一业务块时再加 group。
一个容易忽略的点
Form Layout 控制的是字段放置的位置,不是字段的可见性配置。
如果某个字段不应该显示,应在字段自身的 schema metadata 中设置可见性。仅仅不把它写进 formLayout,并不等同于隐藏该字段;可见字段仍可能出现在表单末尾。
小结
Form Layout 让我们可以在 DTO 中描述复杂表单的结构:
- 用
field决定字段顺序; - 用
section做响应式分栏; - 用
group表达业务分组; - 用
tabs/tab拆分独立内容。
记住这个分工就够了:DTO 描述字段结构,schema 和表单运行时继续处理字段本身的行为。 当表单字段增加或调整时,我们只需要同步修改 DTO 中的布局配置,而不必在多个页面重复维护字段排列。