- UI组件
- 前端
【免费下载链接】ng-zorro-antd
Angular UI Component Library based on Ant Design
导读
ng-zorro-antd 的 Form 组件支持horizontal、vertical、inline三种表单布局,默认情况下整个<form nz-form>只有一个统一布局。当业务场景需要在同一张表单内混排不同排版(例如前几行使用水平布局、后几行改为垂直布局)时,官方提供了一种轻量级方案——直接在nz-form-item上单独设置nzLayout属性,即可在不拆分表单的情况下实现"表单混合布局"。本文基于 mix-layout 演示(自 v21.3.0 起可用),结合源码实现讲解其用法、原理与最佳实践,读完即可在项目中落地单表单多布局的排版能力。
核心思路:布局下放到表单项
<form nz-form>上的[nzLayout]定义整个表单的布局,取值有三种(见 form.directive.ts 中的NzFormLayoutType):
| 取值 | 效果 |
|---|---|
horizontal | 标签与控件水平对齐(默认值) |
vertical | 标签与控件垂直堆叠 |
inline | 表单字段单行内联渲染 |
而混合布局的关键在于:nz-form-item组件自身也支持nzLayout输入,其类型为'horizontal' \| 'vertical'(见 types.ts 中的NzFormItemLayout)。当为某个nz-form-item显式设置了nzLayout时,该表单项的布局将覆盖表单级布局,从而在一个<form nz-form>内同时呈现多种布局样式。
需要特别说明的是,该属性在 Form API 文档 中标注为v21.3.0 新增,且nz-form-item只支持horizontal与vertical两种取值——inline是表单级概念,不在表单项级混合布局的范围内。
完整示例:一个表单里同时出现水平与垂直布局
官方 mix-layout.ts 演示了两种方向的混合:水平表单中嵌入垂直表单项、垂直表单中嵌入水平表单项。完整代码如下:
import { Component } from '@angular/core'; import { NzDividerModule } from 'ng-zorro-antd/divider'; import { NzFormModule } from 'ng-zorro-antd/form'; import { NzInputModule } from 'ng-zorro-antd/input'; @Component({ selector: 'nz-demo-form-mix-layout', imports: [NzDividerModule, NzFormModule, NzInputModule], template: ` <!-- 场景一:整体为 horizontal,中间穿插 vertical 表单项 --> <form nz-form nzLayout="horizontal"> <nz-form-item> <nz-form-label [nzSpan]="4">horizontal</nz-form-label> <nz-form-control [nzSpan]="20"> <input nz-input /> </nz-form-control> </nz-form-item> <nz-form-item nzLayout="vertical"> <nz-form-label>vertical</nz-form-label> <nz-form-control> <input nz-input /> </nz-form-control> </nz-form-item> <nz-form-item nzLayout="vertical"> <nz-form-label>vertical2</nz-form-label> <nz-form-control> <input nz-input /> </nz-form-control> </nz-form-item> </form> <nz-divider /> <!-- 场景二:整体为 vertical,中间穿插 horizontal 表单项 --> <form nz-form nzLayout="vertical"> <nz-form-item> <nz-form-label>vertical</nz-form-label> <nz-form-control> <input nz-input /> </nz-form-control> </nz-form-item> <nz-form-item> <nz-form-label>vertical2</nz-form-label> <nz-form-control> <input nz-input /> </nz-form-control> </nz-form-item> <nz-form-item nzLayout="horizontal"> <nz-form-label [nzSpan]="4">horizontal</nz-form-label> <nz-form-control [nzSpan]="20"> <input nz-input /> </nz-form-control> </nz-form-item> </form> `, styles: ` form { max-width: 600px; } ` }) export class NzDemoFormMixLayoutComponent {}示例中的关键细节值得注意:
- 水平表单项需要配合栅格列宽:在
horizontal布局下,nz-form-label与nz-form-control会继承nz-col的栅格 API(如nzSpan),因此示例中水平表单项设置了[nzSpan]="4"与[nzSpan]="20"来控制标签与控件的宽度比例;而vertical表单项无需设置栅格,标签与控件各占整行。 - 未设置
nzLayout的表单项沿用表单级布局:场景一中未写nzLayout的第一个表单项保持horizontal,场景二中未写nzLayout的前两个表单项保持vertical,只有显式指定的项被覆盖。 - 模块依赖只需引入
NzFormModule(包含nz-form指令、nz-form-item、nz-form-label、nz-form-control等)、NzInputModule与NzDividerModule,与普通表单用法完全一致。
原理剖析:nzLayout如何落到 CSS 类上
混合布局之所以能生效,源于nz-form-item组件对nzLayout输入与 CSS 类的绑定。查看 form-item.component.ts 的 host 绑定:
host: { class: 'ant-form-item', '[class.ant-form-item-horizontal]': 'nzLayout() === "horizontal"', '[class.ant-form-item-vertical]': 'nzLayout() === "vertical"' }组件通过readonly nzLayout = input<NzFormItemLayout>()(信号输入)接收布局值,并据此为宿主元素动态添加ant-form-item-horizontal或ant-form-item-vertical类;当nzLayout未设置时,两个类都不会添加,表单项外观由表单级类(ant-form-horizontal/ant-form-vertical/ant-form-inline)决定。对应地,form.directive.ts 中表单级布局也是通过类似方式绑定ant-form-horizontal、ant-form-vertical、ant-form-inline类。
样式层面,表单相关 Less 样式分散在 components/form/style 目录下:index.less定义了表单项、标签、控件、错误提示等基础样式,horizontal.less与vertical.less分别提供两种布局的对齐规则。混合布局的最终渲染结果,就是"表单级类 + 表单项级类"叠加后的效果。
这一机制在 form-item.spec.ts 中有专门的测试用例覆盖(should apply item layout class与should support mix layout inside form)。后者构造了两个测试组件——NzTestHorizontalFormWithVerticalItemComponent(<form nz-form nzLayout="horizontal">内嵌<nz-form-item nzLayout="vertical" />)和NzTestVerticalFormWithHorizontalItemComponent(垂直表单内嵌水平表单项),断言:
- 表单元素上正确保留
ant-form-horizontal(或ant-form-vertical)类; - 显式设置了
nzLayout的表单项正确出现ant-form-item-vertical(或ant-form-item-horizontal)类; - 未设置
nzLayout的表单项不出现任何ant-form-item-*布局类,完全由表单级布局接管。
由此可见,混合布局不是通过新增样式规则实现的特殊能力,而是"表单项级布局类 + 表单级布局类"的普通叠加——这正是它轻量、可靠的原因。
进阶讨论:与全局布局切换的关系
混合布局是"静态混排",与 layout 演示 中的"动态切换全局布局"是两种互补思路:
- 全局布局:通过绑定
[nzLayout]="validateForm.controls.formLayout.value"等响应式值,在horizontal/vertical/inline三者之间动态切换整张表单,适合"用户可切换整体排版"的场景; - 混合布局:在静态结构中针对个别表单项覆盖布局,适合"整体布局固定、个别字段需要特殊排版"的场景,例如信息录入表单中,长文本字段希望标签在上、内容占满整行(垂直),而短字段希望标签与输入框同行(水平)。
两种方式可以组合使用:即使表单级nzLayout由变量动态控制,显式设置了nzLayout的表单项仍会保持自己的布局,不受表单级变化影响。
最佳实践与注意事项
结合源码与 demo 用法,落地混合布局时有几点建议:
- 水平表单项务必搭配栅格:
nz-form-item继承nz-row的栅格能力(API 文档注明"所有 nz-row 的 API 都可用于nz-form-item"),nz-form-label与nz-form-control继承nz-col的栅格 API。水平布局下建议通过[nzSpan]、[nzOffset]显式控制列宽(参见 layout.ts 中[nzSpan]="isHorizontal ? 4 : null"的写法),否则标签与控件可能无法按预期对齐。 - 垂直表单项无需栅格:垂直布局下标签与控件自动上下排布、占满整行,这也是示例中垂直项不写
nzSpan的原因。 - 控制表单最大宽度:示例通过
form { max-width: 600px; }限制演示表单宽度,实际项目中可结合栅格nz-row/nz-col控制整体宽度,避免过宽的表单影响阅读体验。 - 版本约束:
nz-form-item的nzLayout属性自v21.3.0起提供,低于该版本需升级后才能使用。 inline不做表单项级覆盖:NzFormItemLayout仅允许'horizontal' | 'vertical',若希望单个字段以内联形式出现,仍需在布局方案上做整体考虑。
小结
表单混合布局是 ng-zorro-antd Form 组件在 v21.3.0 引入的一项小而实用的能力:通过在nz-form-item上设置nzLayout,开发者可以在一个<form nz-form>内自由混排水平与垂直表单项,无需拆分表单或手写覆盖样式。其底层实现是表单级与表单项级 CSS 类的简单叠加,既有 form-item.component.ts 的 host 类绑定作为机制支撑,又有 form-item.spec.ts 的自动化测试保证行为稳定。掌握这一特性后,遇到"同一张表单内多种排版"的需求时即可直接复用官方方案,保持代码与样式的统一。
- UI组件
- 前端
【免费下载链接】ng-zorro-antd
Angular UI Component Library based on Ant Design
相关推荐
Ant Design Form 混合布局:在 Form.Item 上单独设置 layout 实现一表单多布局
Ant Design Form 混合布局:在 Form.Item 上单独设置 layout 实现一表单多布局 在 Ant Design 的 Form 中,默认情
前端UI组件设计系统Element UI表单布局:Form表单分组与校验
Element UI表单布局:Form表单分组与校验 Element UI是一套基于Vue.js 2.0的桌面端组件库,提供了丰富的表单组件和校验功能。本文将详
前端UI组件设计系统ng-zorro-antd Cascader 响应式表单实战:从表单绑定到 Reset 重置清空
ng zorro antd Cascader 响应式表单实战:从表单绑定到 Reset 重置清空 导读 本文以 ng zorro antd 组件库中 casca
UI组件前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考