在 DTO 中使用 Form Layout 配置复杂表单,支持 Tabs/Groups/Sections

字段不多时,让表单自动渲染就足够了。可当表单逐渐包含基本资料、联系方式、业务记录时,我们还会关心:字段怎样分组?哪些字段应该并排?哪些内容应该放进独立页签?

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. tabstab:按业务内容拆分页面

最外层的 tabs 创建一组标签页。这里有两个 tab

  • BasicInformation:基本信息;
  • TrainingRecords:培训记录。

如果一张表单里有多个彼此独立的业务区域,Tab 能帮助读者一次只关注当前内容。字段较少时则不必强行使用 Tab,直接分组通常更直观。

2. group:给相关字段一个明确的归属

基本信息页签中的 group 标题是 StudentProfile。它把姓名、手机号和头像放在"学员资料"这个共同语义下。

可以把 group 理解成一个带标题的业务分组。联系方式、收货地址、审批信息等,也都是适合使用 Group 的场景。

3. section:控制响应式分栏

columns: { default: 1, md: 2 } 表示默认一列,到 md 及以上宽度时改为两列。因此,namemobile 可以在桌面端并排显示,在手机上自然变成上下排列。

4. field:引用 DTO 中已经定义的字段

每个 field 通过 name 对应 DTO schema 中的字段,例如 name。它的输入控件、标题和校验规则仍沿用字段本身已有的定义。

imageIdspan: { 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 中的布局配置,而不必在多个页面重复维护字段排列。

延伸阅读

相关推荐
张人玉2 小时前
Vue 3 + ECharts 智慧城市大屏——赣州智慧城市数据可视化平台
vue.js·echarts·智慧城市
come112342 小时前
Vue 3 与现代 JavaScript 常用语法指南
前端·javascript·vue.js
敖行客Allthinker2 小时前
Vuex 状态响应机制:watch 与 subscribe 的对比分析
vue.js
用户2930750976692 小时前
Vue3 流式 AI 对话:深入理解两个 done 与 buffer 缓存机制
vue.js
Starry-sky(jing)2 小时前
如何判断 Windows 是否安装 Node.js:三种方法 + 常见漏判场景
运维·windows·node.js·环境检测
qq_589666052 小时前
npm install npm install -g @vue/cli 分别是什么意思以及安装路径
前端·vue.js·npm
zzx2006__3 小时前
Ajax➕node.js➕webpack
ajax·webpack·node.js
触底反弹12 小时前
🔥 前端也能玩转 AI 流式输出!从二进制流到打字机效果,一篇讲透
javascript·人工智能·node.js
海上彼尚14 小时前
Nodejs也能写Agent - 16.LangGraph篇 - 条件分支与循环
前端·后端·langchain·node.js