☰
ng-zorro-antd Space 组件分隔符(nzSplit)实战指南:相邻组件优雅分割
2026/9/28 3:33:06 网站建设 项目流程
  • UI组件
  • 前端

【免费下载链接】ng-zorro-antd

Angular UI Component Library based on Ant Design

项目地址:https://gitcode.com/gh_mirrors/ng/ng-zorro-antd
点击查看免费下载

导读

本文聚焦 ng-zorro-antd 布局组件nz-space的分隔符能力([nzSplit]),讲解如何为相邻组件之间插入统一的视觉分隔元素(如竖线、图标、文字),并深入剖析其底层实现原理与测试验证方式。读完本文,你将掌握nzSplit的完整用法、模板上下文细节,以及如何结合nz-divider、nz-space-item指令打造可复用的分割布局方案。

1. 场景与需求:相邻组件为什么要"分隔符"

在 split.md 演示文档中,官方给出了该场景的定义:相邻组件分隔符(Split)。当多个内联组件(如链接、标签、操作按钮)并排排列时,nz-space默认只负责统一间距(basic.md 中定义为"相邻组件水平间距")。但在许多界面中,组件之间除了间距还需要明确的视觉边界,例如:

  • 面包屑或导航中的多个链接之间插入竖线|;
  • 操作栏按钮之间插入分隔线;
  • 文本片段之间插入符号(如/、·)。

这正是nzSplit要解决的问题:在不破坏 Space 统一间距机制的前提下,为任意两个相邻子项之间插入一个模板化分隔元素。

从源码看,该能力由 space.component.ts 的模板循环实现:

@for (item of items; track item) { <div class="ant-space-item"> <ng-container [ngTemplateOutlet]="item" /> </div> @if (nzSplit && !$last) { <span class="ant-space-split"> <ng-template [nzStringTemplateOutlet]="nzSplit" [nzStringTemplateOutletContext]="{ $implicit: $index }">{{ nzSplit }}</ng-template> </span> } }

关键细节一目了然:@if (nzSplit && !$last)保证只有非最后一个子项之后才渲染分隔符,因此 N 个子项恰好产生 N-1 个分隔符,不会出现尾部多余分隔。

2. API 定义:nzSplit 的参数形态

在 index.zh-CN.md 的 API 表中,nzSplit定义如下:

参数说明类型默认值支持全局配置
[nzSplit]设置分隔符TemplateRef \| string--

结合 space.component.ts 的输入声明:

@Input() nzSplit: TemplateRef<{ $implicit: number }> | string | null = null;

可以得到完整的语义说明:

  • 支持TemplateRef或string两种形态,默认值为null(不渲染任何分隔符)。
  • 传入字符串时,会经由NzStringTemplateOutletDirective(来自 core/outlet)渲染为纯文本分隔符,例如'/'。
  • 传入TemplateRef时,模板上下文为{ $implicit: number },其中$implicit是当前分隔符的索引下标(从 0 开始),可在自定义模板中按需取用,实现"不同位置渲染不同分隔符"的高级玩法。
  • 文档 API 表注明该参数不支持全局配置(nzSize才带✅全局配置标记),需要逐组件显式传入。

3. 官方 Demo 逐行解析:竖线分隔的链接组

官方演示 split.ts 给出了最典型、可直接复制运行的完整实现:

import { Component } from '@angular/core'; import { NzDividerModule } from 'ng-zorro-antd/divider'; import { NzSpaceModule } from 'ng-zorro-antd/space'; @Component({ selector: 'nz-demo-space-split', imports: [NzDividerModule, NzSpaceModule], template: ` <nz-space [nzSplit]="spaceSplit"> <ng-template #spaceSplit> <nz-divider nzType="vertical" /> </ng-template> <a *nzSpaceItem>Link</a> <a *nzSpaceItem>Link</a> <a *nzSpaceItem>Link</a> </nz-space> ` }) export class NzDemoSpaceSplitComponent { size = 8; }

要点拆解:

  1. 模块依赖:必须同时导入NzSpaceModule与NzDividerModule。分隔符本身是模板,内部可以使用任何 ng-zorro-antd 组件,其中nz-divider的nzType="vertical"模式正是为"垂直细分隔线"设计的,配合ant-space-split的定位语义最合适。
  2. 模板引用:通过<ng-template #spaceSplit>定义分隔符模板,再以[nzSplit]="spaceSplit"绑定到nz-space。注意nzSplit接收的是TemplateRef,因此传入的是模板引用变量而非模板字符串。
  3. 子项标记:每个子元素通过*nzSpaceItem结构性指令标记为 Space 子项。该指令定义于 space-item.directive.ts,本身是空壳标记指令,组件通过@ContentChildren(NzSpaceItemDirective, { read: TemplateRef })收集子项模板(见 space.component.ts)。
  4. 间距协同:nzSplit与默认间距机制并存——分隔符渲染在间距(column-gap/row-gap)之外,既保留nzSize的等距效果,又额外提供视觉边界。

从样式层看,index.less 将容器定义为display: inline-flex,各子项包裹在.ant-space-item中,分隔符包裹在.ant-space-split中,天然支持水平/垂直排列(-vertical时flex-direction: column)与align-items对齐控制。

4. 纵深原理:源码如何组织"子项 + 分隔符"

4.1 收集子项

组件通过@ContentChildren收集所有带有*nzSpaceItem指令的子元素模板(space.component.ts):

@ContentChildren(NzSpaceItemDirective, { read: TemplateRef }) items!: QueryList<TemplateRef<NzSafeAny>>;

并在ngAfterContentInit中订阅items.changes,当子项动态增删时触发变更检测(space.component.ts),保证nzSplit分隔符数量随子项数量实时同步。

4.2 渲染策略:分隔符不进 flex 间距

模板循环将每个子项包进<div class="ant-space-item">,分隔符则是独立的<span class="ant-space-split">,二者作为 flex 容器内的平级元素。间距通过宿主上的column-gap/row-gap样式实现(space.component.ts),因此分隔符不会"吃掉"子项之间的统一间距,也不会被误算进子项尺寸。

4.3 对齐与方向协同

nzSplit与nzDirection、nzAlign完全兼容:

  • 水平排列(默认)时,mergedAlign缺省为center,竖线分隔符与子项垂直居中对齐;
  • 垂直排列(nzDirection="vertical")时同样支持分隔符,可在纵向列表项之间插入分隔线。

相关类型定义见 types.ts:

export type NzSpaceDirection = 'vertical' | 'horizontal'; export type NzSpaceAlign = 'start' | 'end' | 'center' | 'baseline'; export type NzSpaceSize = 'small' | 'middle' | 'large' | number;

5. 测试验证:分隔符的数量与渲染行为

space.component.spec.ts 中针对nzSplit的测试用例直接印证了上述渲染逻辑:

template: ` <nz-space [nzSplit]="showSplit() ? spaceSplit : null" [nzSize]="size()" [nzDirection]="direction()" [nzAlign]="align()" [nzWrap]="wrap()" > <div *nzSpaceItem>item</div> <div *nzSpaceItem>item</div> @if (show()) { <div *nzSpaceItem>item</div> } </nz-space> <ng-template #spaceSplit>|</ng-template> `

断言逻辑(space.component.spec.ts):

  • 初始 2 个子项且启用分隔符时,.ant-space-split的数量为1(即 N-1);
  • 动态新增第 3 个子项后,分隔符数量同步变为2;
  • 同时验证了column-gap与row-gap均为8px,证明间距机制与分隔符机制互不干扰。

这组测试同时也演示了nzSplit的另一个能力:传入null即可完全关闭分隔符渲染(@if (nzSplit && !$last)中nzSplit为假值时整段不渲染),适合做条件性分隔。

6. 进阶用法与最佳实践

6.1 字符串分隔符

不需要模板时,直接传字符串即可渲染文本分隔符:

<nz-space nzSplit="/"> <a *nzSpaceItem>Home</a> <a *nzSpaceItem>Products</a> <a *nzSpaceItem>About</a> </nz-space>

渲染效果为Home / Products / About,适合路径指示、标签序列等轻量场景。

6.2 利用模板上下文区分位置

模板上下文提供$implicit: number(分隔符索引),可以按位置差异化渲染:

<nz-space [nzSplit]="splitTpl"> <ng-template #splitTpl let-index> @if (index % 2 === 0) { <nz-divider nzType="vertical" /> } @else { <span class="custom-dot">·</span> } </ng-template> ... </nz-space>

6.3 与紧凑模式(nz-space-compact)的区别

需要明确的是,nzSplit属于普通nz-space的视觉分隔能力;而表单组件(Button、Input、Select、DatePicker 等)之间需要合并边框的紧凑连接时,应使用<nz-space-compact>(支持组件清单与参数见 index.zh-CN.md)。两者适用场景不同,nzSplit面向"有间距 + 有分隔"的组合布局。

6.4 使用前提

  • 需要 Angular 17+ 模板新语法(@for/@if)支持(源码模板基于新控制流编写);
  • 使用前请确认已导入NzSpaceModule及分隔符所依赖的组件模块(如示例中的NzDividerModule);
  • nzSplit不支持通过全局配置(NZ_CONFIG)统一下发,需逐组件显式设置。

7. 小结

nzSplit为nz-space提供了"间距 + 分隔符"的组合布局能力:以TemplateRef | string两种形态灵活定义分隔内容,由源码模板保证 N 个子项恰好渲染 N-1 个分隔符,且与方向、对齐、间距、换行等既有参数完全兼容。结合 split.ts 的可运行示例、space.component.ts 的底层实现与 space.component.spec.ts 的测试佐证,开发者可以快速在自己的页面中落地这一能力。

  • UI组件
  • 前端

【免费下载链接】ng-zorro-antd

Angular UI Component Library based on Ant Design

项目地址:https://gitcode.com/gh_mirrors/ng/ng-zorro-antd
点击查看免费下载
上一篇:3 行代码移除图片背景:Rembg 抠图快速上手完整指南
下一篇:3分钟掌握N_m3u8DL-CLI-SimpleG:零基础视频下载终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询