- UI组件
- 前端
【免费下载链接】ng-zorro-antd
Angular UI Component Library based on Ant Design
本篇指南围绕 NG-ZORRO(ng-zorro-antd)的 Descriptions(描述列表)组件展开,基于其官方文档 components/descriptions/doc/index.en-US.md 中的 API 定义,结合 主组件源码 与 测试用例 深入讲解:如何分组展示多个只读字段、nzColumn响应式列数如何按断点生效、nzSpan参与行排布的底层算法,以及nzBordered、nzLayout、nzSize等属性在模板中的实际渲染差异。读完后可掌握描述列表的完整用法、布局原理与常见警告的成因。
组件定位:详情页中的只读字段分组展示
官方文档对 Descriptions 的定位非常明确:
Display multiple read-only fields in a group.(以分组形式展示多个只读字段。)
其典型使用场景是详情页(Commonly displayed on the details page)——例如用户信息页、订单信息页、资源实例详情页,需要将"用户名 / 电话 / 地址"等一组键值对字段以整齐的网格形式呈现。组件属于数据展示(Data Display)类别,由两个核心构件组成:
| 构件 | 选择器 | 源码位置 |
|---|---|---|
| 描述列表容器 | nz-descriptions | descriptions.component.ts |
| 描述列表项 | nz-descriptions-item | descriptions-item.component.ts |
两者均通过NzDescriptionsModule对外导出(见 public-api.ts 与 descriptions.module.ts),也可作为独立组件按需导入。
快速上手
在组件中导入NzDescriptionsModule后,即可声明式地定义标题、字段与内容。以下示例与官方示例 basic.ts 一致:
import { Component } from '@angular/core'; import { NzDescriptionsModule } from 'ng-zorro-antd/descriptions'; @Component({ selector: 'nz-demo-descriptions-basic', imports: [NzDescriptionsModule], template: ` <nz-descriptions nzTitle="User Info"> <nz-descriptions-item nzTitle="UserName">Zhou Maomao</nz-descriptions-item> <nz-descriptions-item nzTitle="Telephone">18100000000</nz-descriptions-item> <nz-descriptions-item nzTitle="Live">Hangzhou, Zhejiang</nz-descriptions-item> <nz-descriptions-item nzTitle="Remark">Empty</nz-descriptions-item> <nz-descriptions-item nzTitle="Address"> No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China </nz-descriptions-item> </nz-descriptions> ` }) export class NzDemoDescriptionsBasicComponent {}对应的静态示例文档见 demo/basic.md。更多官方示例(带边框、响应式、纵向布局、自定义尺寸)分别位于 demo/border.md、demo/responsive.md、demo/vertical.md、demo/custom-size.md。
nz-descriptions 属性详解
官方文档给出的容器属性表如下(此处完整继承,并补充源码默认值说明):
| Property | Description | Type | Default | Global Config |
|---|---|---|---|---|
[nzTitle] | 列表标题,显示在顶部 | string \| TemplateRef<void> | false | |
[nzExtra] | 操作区域,置于右上角 | string \| TemplateRef<void> | - | |
[nzBordered] | 是否显示边框 | boolean | false | ✅ |
[nzColumn] | 每行nz-descriptions-item的数量,可为数字或{ xs: 8, sm: 16, md: 24 }这类对象 | number \| object | { xxl: 3, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 } | ✅ |
[nzSize] | 列表尺寸,仅在nzBordered开启时生效 | 'default' \| 'middle' \| 'small' | 'default' | ✅ |
[nzColon] | 标题后是否显示冒号 | boolean | true | ✅ |
[nzLayout] | 列表布局方式 | 'horizontal' \| 'vertical' | 'horizontal' |
对照 descriptions.component.ts 的@Input声明,可以确认文档与源码的对应关系:
@Input({ transform: booleanAttribute }) @WithConfig() nzBordered: boolean = false; @Input() nzLayout: NzDescriptionsLayout = 'horizontal'; @Input() @WithConfig() nzColumn: number | Partial<ResponsiveLike<number>> = defaultColumnMap; @Input() @WithConfig() nzSize: NzDescriptionsSize = 'default'; @Input() nzTitle: string | TemplateRef<void> = ''; @Input() nzExtra?: string | TemplateRef<void>; @Input({ transform: booleanAttribute }) @WithConfig() nzColon: boolean = true;几个值得注意的实现细节:
nzBordered与nzColon使用booleanAttribute转换,因此模板中nzBordered不带值绑定时会按布尔属性规则解析;nzColumn的完整内置默认值:源码中的defaultColumnMap(descriptions.component.ts)实际为{ xxxl: 4, xxl: 3, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 },即文档默认值之外还包含xxxl: 4一档;当传入对象缺少当前断点时,回退常量为DEFAULT_COLUMN_NUM = 3;nzTitle/nzExtra支持TemplateRef:模板中通过*nzStringTemplateOutlet渲染(descriptions.component.ts),所以nzExtra可以传入模板引用,放置按钮等操作内容,官方示例 custom-size.ts 就传入了一个包含"Edit"按钮的#extraTpl模板;nzSize的实现:源码在 host 上按值绑定ant-descriptions-middle/ant-descriptions-small类名(descriptions.component.ts),文档同时声明该属性仅在nzBordered开启时生效,即边框样式下的密度调整(行高、内边距等由样式层控制)。
nz-descriptions-item 属性与 nzSpan
列表项的属性如下(与官方文档一致):
| Property | Description | Type | Default |
|---|---|---|---|
[nzTitle] | 内容对应的标题 | string \| TemplateRef<void> | - |
[nzSpan] | 该项跨占的列数 | number | 1 |
从 descriptions-item.component.ts 的实现看,每个 item 本身并不渲染任何可见结构——它的模板只是一个包裹<ng-content />的<ng-template>(descriptions-item.component.ts)。item 的真实渲染由父组件nz-descriptions统一接管:父组件通过@ContentChildren(NzDescriptionsItemComponent)收集所有子项,取其nzTitle、nzSpan与内容模板重新组装成表格行(下文详述)。
nzSpan支持numberAttribute转换,因此[nzSpan]="2"这种数字绑定方式是被明确支持的。带边框示例 border.ts 中可以看到典型的跨列用法:
<z-descriptions-item nzTitle="Usage Time" [nzSpan]="2"> 2018-04-24 18:00:00 To 2019-04-24 18:00:00 </nz-descriptions-item> <z-descriptions-item nzTitle="Status" [nzSpan]="3"> <nz-badge nzStatus="processing" nzText="Running" /> </z-descriptions-item>行排布算法:prepareMatrix 如何把 items 铺成行
理解 Descriptions 的布局行为,关键在于源码中 prepareMatrix() 的排布算法。它维护一个累加宽度width,按顺序遍历所有 item:
- 将当前 item 的
nzSpan累加到width; - 若
width >= column(达到一行容量),该 item 的实际跨列被改写为column - (width - span)——即让最后一个 item 吃掉整行剩余空间,然后换行并清零; - 若
width > column(超出一行容量),源码会调用warn输出类似"nzColumn" is 3 but we have row length 5的告警,但仍按"填满剩余空间"处理; - 若遍历到最后一个 item 且未达行容量,同样按剩余空间补齐(
i === length - 1分支)。
这段逻辑解释了两个常见行为:
- 行内最后一项自动拉伸:例如
nzColumn为 3、items 的 span 为[1, 1]时,第二项会以colSpan=2渲染。测试用例 专门验证了这一点:colspanArray设为[1, 1]后断言第二个td的colSpan为 4(nzColumn为 5 时)。 - span 总和超过
nzColumn的告警:descriptions.spec.ts 中断言了'"nzColumn" is 3 but we have row length 5'、'"nzColumn" is 3 but we have row length 6'等警告文本,且行数按"溢出截断到一行"的方式计算(span 为[1, 1, 1, 2, 3, 1, 5]时得到 3 行)。遇到控制台告警时应检查各行 item 的nzSpan之和是否小于等于nzColumn。
排布的触发时机也值得注意:ngAfterContentInit中监听了三路信号——item 列表的增删(items.changes)、各 item 输入变化(inputChange$,带 16msauditTime节流)、以及断点服务(descriptions.component.ts),任一变化都会重算itemMatrix并markForCheck。这意味着nzSpan、nzTitle的动态变更和窗口尺寸变化都能驱动重新布局,测试用例 验证了内容切换后标题能正确刷新。
模板渲染差异:bordered 与非 bordered 的表格结构
nz-descriptions的内容区最终渲染为一个<table>(外层.ant-descriptions-view,descriptions.component.ts),nzBordered与nzLayout决定了完全不同的单元格结构:
nzLayout="horizontal"+ 无边框:每个 item 占一个<td class="ant-descriptions-item">,colSpan=item.span,标签与内容以span.ant-descriptions-item-label/ant-descriptions-item-content横向排布在同一格内;nzLayout="horizontal"+nzBordered:每个 item 拆成两个格子——标签格<td class="ant-descriptions-item-label">与内容格<td class="ant-descriptions-item-content">,内容格的colSpan = item.span * 2 - 1(descriptions.component.ts)。也就是说边框模式下内部表格列数是nzColumn的两倍,跨列跨度会被放大计算;nzLayout="vertical":标签行与内容行拆成两条<tr>交替出现,边框与非边框两种变体分别对应不同单元格类名(descriptions.component.ts),标签在上、内容在下。
官方示例 vertical.ts 展示了nzLayout="vertical"的用法,其中"Address" 项通过[nzSpan]="2"让长地址跨两列;vertical-border.ts 则演示了边框模式下的纵向布局。
nzColon作用于无边框横向模式下的标签:源码中通过[class.ant-descriptions-item-no-colon]="!nzColon"切换类名(descriptions.component.ts),关闭后标签后的冒号样式被移除。
响应式列数:nzColumn 与断点联动
nzColumn既可传数字(所有断点统一),也可传对象按断点配置。官方示例 responsive.ts:
<z-descriptions nzTitle="Responsive Descriptions" nzBordered [nzColumn]="{ xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 }" > <nz-descriptions-item nzTitle="Product">Cloud Database</nz-descriptions-item> <nz-descriptions-item nzTitle="Billing">Prepaid</nz-descriptions-item> <nz-descriptions-item nzTitle="time">18:00:00</nz-descriptions-item> <!-- 其余 items 省略,共 7 项 --> </nz-descriptions>底层机制见 getColumn():
private getColumn(): number { if (typeof this.nzColumn !== 'number') { return this.nzColumn[this.breakpoint] ?? DEFAULT_COLUMN_NUM; } return this.nzColumn; }- 断点值来自注入的
NzBreakpointService,组件在初始化时以gridResponsiveMap订阅断点变化(descriptions.component.ts),窗口 resize 会触发breakpoint更新并调用prepareMatrix()重排; - 对象中缺失的断点回退到
DEFAULT_COLUMN_NUM = 3,因此传{ xs: 1 }这类部分配置是安全的; - 当
nzColumn被外部改动(ngOnChanges)时同样会立即重排(descriptions.component.ts)。
响应式测试用例 模拟了视口从 1024px 到 320px 的变化:断点命中md时同一组 item 排成 3 行,缩小到xs(单列)后排成 7 行,验证了断点驱动的列数切换。另一个针对 resize 的回归测试(descriptions.spec.ts,注释标注 fix #9927)则确认了"缩小再放大窗口后 item 内容不丢失"。
全局配置
API 表中标注 ✅ 的属性(nzBordered、nzColumn、nzSize、nzColon)都带@WithConfig()装饰器,且组件声明了配置键:
const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'descriptions'; // ... readonly _nzModuleName: NzConfigKey = NZ_CONFIG_MODULE_NAME;即这些属性可纳入 NG-ZORRO 的全局配置机制,在应用层面以descriptions为模块名统一覆盖默认值(例如全局开启nzBordered、统一nzColon策略),各组件内未显式绑定的输入将回落到全局配置。全局配置的整体用法可参考 docs/global-config.zh-CN.md。而nzLayout无全局配置标记,需在模板中逐处设置。
RTL 支持与验证方式
从源码结构看,nz-descriptions的 host 绑定了[class.ant-descriptions-rtl]="dir() === 'rtl'"(descriptions.component.ts),依赖@angular/cdk/bidi的Directionality信号实现从右到左布局的类名切换;RTL 测试 验证了dir在rtl与ltr间切换时ant-descriptions-rtl类名的增删。
日常开发中可参考 descriptions.spec.ts 的断言方式自验组件行为:
- 通过
.ant-descriptions-row数量验证行数是否符合nzColumn/nzSpan组合预期; - 通过
td的colSpan验证跨列与"末项补满"行为; - 通过
console.warn的 spy 验证列宽溢出告警文本。
样式层面,组件样式入口位于 style/index.less,另有 patch.less 处理覆盖细节;类名前缀为ant-descriptions(host 绑定class: 'ant-descriptions',descriptions.component.ts)。
小结
Descriptions 以"父组件收集 item、统一铺排表格"的架构,把布局复杂度集中在 prepareMatrix() 一处:nzColumn决定列容量(数字或按断点响应),nzSpan决定单项占宽,末项自动补满剩余空间、溢出时给出明确告警。掌握"行内 span 之和 ≤ 当前断点列数"这一约束,配合nzBordered/nzLayout/nzSize的外观开关与nzTitle/nzExtra的头部能力,即可在各类详情页中稳定构建 Ant Design 风格的描述列表。
- UI组件
- 前端
【免费下载链接】ng-zorro-antd
Angular UI Component Library based on Ant Design
相关推荐
ng-zorro-antd Descriptions 响应式布局:nzColumn 断点配置与源码解析
ng zorro antd Descriptions 响应式布局:nzColumn 断点配置与源码解析 ng zorro antd 的 Descriptions
UI组件前端ng-zorro-antd 描述列表实战:nz-descriptions 垂直布局与边框模式的完整实现解析
ng zorro antd 描述列表实战:nz descriptions 垂直布局与边框模式的完整实现解析 在 ng zorro antd 中, nz desc
UI组件前端ng-zorro-antd 描述列表带边框模式实战:nzBordered、nzSpan 与表格化渲染原理
ng zorro antd 描述列表带边框模式实战:nzBordered、nzSpan 与表格化渲染原理 本篇围绕 ng zorro antd 中 nz des
UI组件前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考