Tabs标签页

选项卡切换组件。

何时使用

提供平级的区域将大块内容进行收纳和展现,保持界面整洁。

Ant Design 依次提供了三级选项卡,分别用于不同的场景。

  • 卡片式的页签,提供可关闭的样式,常用于容器顶部。
  • 标准线条式页签,用于容器内部的主功能切换,这是最常用的 Tabs。
  • RadioButton 可作为更次级的页签来使用。
  1. import { NzTabsModule } from 'ng-zorro-antd/tabs';

代码演示Tabs标签页 - 图2

Tabs标签页 - 图3

基本

默认选中第一项。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'nz-demo-tabs-basic',
  4. template: `
  5. <nz-tabset>
  6. <nz-tab nzTitle="Tab 1">
  7. Content of Tab Pane 1
  8. </nz-tab>
  9. <nz-tab nzTitle="Tab 2">
  10. Content of Tab Pane 2
  11. </nz-tab>
  12. <nz-tab nzTitle="Tab 3">
  13. Content of Tab Pane 3
  14. </nz-tab>
  15. </nz-tabset>
  16. `
  17. })
  18. export class NzDemoTabsBasicComponent {}

Tabs标签页 - 图4

禁用

禁用某一项。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'nz-demo-tabs-disabled',
  4. template: `
  5. <nz-tabset>
  6. <nz-tab *ngFor="let tab of tabs" [nzTitle]="tab.name" [nzDisabled]="tab.disabled">
  7. {{ tab.name }}
  8. </nz-tab>
  9. </nz-tabset>
  10. `
  11. })
  12. export class NzDemoTabsDisabledComponent {
  13. tabs = [
  14. {
  15. name: 'Tab 1',
  16. disabled: false
  17. },
  18. {
  19. name: 'Tab 2',
  20. disabled: true
  21. },
  22. {
  23. name: 'Tab 3',
  24. disabled: false
  25. }
  26. ];
  27. }

Tabs标签页 - 图5

图标

有图标的标签。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'nz-demo-tabs-icon',
  4. template: `
  5. <nz-tabset>
  6. <nz-tab *ngFor="let tab of tabs" [nzTitle]="titleTemplate">
  7. <ng-template #titleTemplate>
  8. <i nz-icon [nzType]="tab.icon"></i>
  9. {{ tab.name }}
  10. </ng-template>
  11. {{ tab.name }}
  12. </nz-tab>
  13. </nz-tabset>
  14. `
  15. })
  16. export class NzDemoTabsIconComponent {
  17. tabs = [
  18. {
  19. name: 'Tab 1',
  20. icon: 'apple'
  21. },
  22. {
  23. name: 'Tab 2',
  24. icon: 'android'
  25. }
  26. ];
  27. }

Tabs标签页 - 图6

滑动

可以左右、上下滑动,容纳更多标签。

  1. import { Component, OnInit } from '@angular/core';
  2. import { NzTabPosition } from 'ng-zorro-antd/tabs';
  3. @Component({
  4. selector: 'nz-demo-tabs-slide',
  5. template: `
  6. <nz-radio-group [(ngModel)]="nzTabPosition" style="margin-bottom: 8px;">
  7. <label nz-radio-button [nzValue]="'top'">Horizontal</label>
  8. <label nz-radio-button [nzValue]="'left'">Vertical</label>
  9. </nz-radio-group>
  10. <nz-input-number style="float:right;" [nzMin]="0" [nzMax]="29" [(ngModel)]="selectedIndex"></nz-input-number>
  11. <nz-tabset style="height:220px;" [nzTabPosition]="nzTabPosition" [(nzSelectedIndex)]="selectedIndex" (nzSelectChange)="log([$event])">
  12. <nz-tab
  13. *ngFor="let tab of tabs"
  14. [nzTitle]="tab.name"
  15. [nzDisabled]="tab.disabled"
  16. (nzSelect)="log(['select', tab])"
  17. (nzClick)="log(['click', tab])"
  18. (nzContextmenu)="log(['contextmenu', tab])"
  19. (nzDeselect)="log(['deselect', tab])"
  20. >
  21. {{ tab.content }}
  22. </nz-tab>
  23. </nz-tabset>
  24. `
  25. })
  26. export class NzDemoTabsSlideComponent implements OnInit {
  27. tabs: Array<{ name: string; content: string; disabled: boolean }> = [];
  28. nzTabPosition: NzTabPosition = 'top';
  29. selectedIndex = 0;
  30. /* tslint:disable-next-line:no-any */
  31. log(args: any[]): void {
  32. console.log(args);
  33. }
  34. ngOnInit(): void {
  35. for (let i = 0; i < 30; i++) {
  36. this.tabs.push({
  37. name: `Tab ${i}`,
  38. disabled: i === 28,
  39. content: `Content of tab ${i}`
  40. });
  41. }
  42. }
  43. }

Tabs标签页 - 图7

附加内容

可以在页签右边添加附加操作。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'nz-demo-tabs-extra',
  4. template: `
  5. <nz-tabset [nzTabBarExtraContent]="extraTemplate">
  6. <nz-tab *ngFor="let tab of tabs" [nzTitle]="'Tab ' + tab">Content of tab {{ tab }}</nz-tab>
  7. </nz-tabset>
  8. <ng-template #extraTemplate>
  9. <button nz-button>Extra Action</button>
  10. </ng-template>
  11. `
  12. })
  13. export class NzDemoTabsExtraComponent {
  14. tabs = [1, 2, 3];
  15. }

Tabs标签页 - 图8

大小

大号页签用在页头区域,小号用在弹出框等较狭窄的容器内。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'nz-demo-tabs-size',
  4. template: `
  5. <nz-radio-group [(ngModel)]="size">
  6. <label nz-radio-button nzValue="small"><span>Small</span></label>
  7. <label nz-radio-button nzValue="default"><span>Default</span></label>
  8. <label nz-radio-button nzValue="large"><span>Large</span></label>
  9. </nz-radio-group>
  10. <nz-tabset [nzSize]="size">
  11. <nz-tab *ngFor="let tab of tabs" [nzTitle]="'Tab ' + tab">Content of tab {{ tab }}</nz-tab>
  12. </nz-tabset>
  13. `
  14. })
  15. export class NzDemoTabsSizeComponent {
  16. size: 'large' | 'default' | 'small' = 'small';
  17. tabs = [1, 2, 3];
  18. }

Tabs标签页 - 图9

位置

有四个位置,nzTabPosition="left|right|top|bottom"

  1. import { Component } from '@angular/core';
  2. import { NzTabPosition } from 'ng-zorro-antd/tabs';
  3. @Component({
  4. selector: 'nz-demo-tabs-position',
  5. template: `
  6. <div style="margin-bottom: 16px;">
  7. Tab position:
  8. <nz-select [(ngModel)]="position" style="width: 80px;">
  9. <nz-option *ngFor="let option of options" [nzLabel]="option.label" [nzValue]="option.value"></nz-option>
  10. </nz-select>
  11. </div>
  12. <nz-tabset [nzTabPosition]="position">
  13. <nz-tab *ngFor="let tab of tabs" [nzTitle]="'Tab ' + tab">Content of tab {{ tab }}</nz-tab>
  14. </nz-tabset>
  15. `
  16. })
  17. export class NzDemoTabsPositionComponent {
  18. position: NzTabPosition = 'top';
  19. tabs = [1, 2, 3];
  20. options = [
  21. { value: 'top', label: 'top' },
  22. { value: 'left', label: 'left' },
  23. { value: 'right', label: 'right' },
  24. { value: 'bottom', label: 'bottom' }
  25. ];
  26. }

Tabs标签页 - 图10

卡片式页签

另一种样式的页签,不提供对应的垂直样式。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'nz-demo-tabs-card',
  4. template: `
  5. <nz-tabset nzType="card">
  6. <nz-tab *ngFor="let tab of tabs" [nzTitle]="'Tab' + tab">Content of Tab Pane {{ tab }}</nz-tab>
  7. </nz-tabset>
  8. `
  9. })
  10. export class NzDemoTabsCardComponent {
  11. tabs = [1, 2, 3];
  12. }

Tabs标签页 - 图11

新增和关闭页签

只有卡片样式的页签支持新增和关闭选项。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'nz-demo-tabs-editable-card',
  4. template: `
  5. <nz-tabset [(nzSelectedIndex)]="selectedIndex" nzType="editable-card" (nzAdd)="newTab()" (nzClose)="closeTab($event)">
  6. <nz-tab *ngFor="let tab of tabs" nzClosable [nzTitle]="tab">Content of {{ tab }}</nz-tab>
  7. </nz-tabset>
  8. `
  9. })
  10. export class NzDemoTabsEditableCardComponent {
  11. tabs = ['Tab 1', 'Tab 2'];
  12. selectedIndex = 0;
  13. closeTab({ index }: { index: number }): void {
  14. this.tabs.splice(index, 1);
  15. }
  16. newTab(): void {
  17. this.tabs.push('New Tab');
  18. this.selectedIndex = this.tabs.length;
  19. }
  20. }

Tabs标签页 - 图12

卡片式页签容器

用于容器顶部,需要一点额外的样式覆盖。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'nz-demo-tabs-card-top',
  4. template: `
  5. <div class="card-container">
  6. <nz-tabset nzType="card">
  7. <nz-tab *ngFor="let tab of tabs" [nzTitle]="'Tab Title ' + tab">
  8. <p>Content of Tab Pane {{ tab }}</p>
  9. <p>Content of Tab Pane {{ tab }}</p>
  10. <p>Content of Tab Pane {{ tab }}</p>
  11. </nz-tab>
  12. </nz-tabset>
  13. </div>
  14. `,
  15. styles: [
  16. `
  17. :host {
  18. background: #f5f5f5;
  19. overflow: hidden;
  20. padding: 24px;
  21. display: block;
  22. }
  23. .card-container ::ng-deep p {
  24. margin: 0;
  25. }
  26. .card-container ::ng-deep > .ant-tabs-card .ant-tabs-content {
  27. height: 120px;
  28. margin-top: -16px;
  29. }
  30. .card-container ::ng-deep > .ant-tabs-card .ant-tabs-content > .ant-tabs-tabpane {
  31. background: #fff;
  32. padding: 16px;
  33. }
  34. .card-container ::ng-deep > .ant-tabs-card > .ant-tabs-nav::before {
  35. display: none;
  36. }
  37. .card-container ::ng-deep > .ant-tabs-card .ant-tabs-tab {
  38. border-color: transparent;
  39. background: transparent;
  40. }
  41. .card-container ::ng-deep > .ant-tabs-card .ant-tabs-tab-active {
  42. border-color: #fff;
  43. background: #fff;
  44. }
  45. `
  46. ]
  47. })
  48. export class NzDemoTabsCardTopComponent {
  49. tabs = [1, 2, 3];
  50. }

Tabs标签页 - 图13

自定义新增页签触发器

给自定义触发器绑定事件。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'nz-demo-tabs-custom-add-trigger',
  4. template: `
  5. <div style="margin-bottom: 16px;">
  6. <button nz-button (click)="newTab()">ADD</button>
  7. </div>
  8. <nz-tabset [(nzSelectedIndex)]="index" nzType="editable-card" nzHideAdd (nzClose)="closeTab($event)">
  9. <nz-tab *ngFor="let tab of tabs; let i = index" [nzClosable]="i > 1" [nzTitle]="tab">Content of {{ tab }}</nz-tab>
  10. </nz-tabset>
  11. `
  12. })
  13. export class NzDemoTabsCustomAddTriggerComponent {
  14. index = 0;
  15. tabs = ['Tab 1', 'Tab 2'];
  16. closeTab({ index }: { index: number }): void {
  17. this.tabs.splice(index, 1);
  18. }
  19. newTab(): void {
  20. this.tabs.push('New Tab');
  21. this.index = this.tabs.length - 1;
  22. }
  23. }

Tabs标签页 - 图14

懒加载

默认情况下,nz-tab 中的组件的 ngOnInit 会提前触发,如果希望当 Tab 被激活时再触发 ngOnInit,可以使用该示例中的懒加载方式。

  1. /* declarations: NzDemoTabContentLazyComponent,NzDemoTabContentEagerlyComponent */
  2. import { Component, OnInit } from '@angular/core';
  3. @Component({
  4. selector: 'nz-demo-tabs-lazy',
  5. template: `
  6. <nz-tabset>
  7. <nz-tab nzTitle="Tab Eagerly 1">
  8. <nz-demo-tab-content-eagerly></nz-demo-tab-content-eagerly>
  9. </nz-tab>
  10. <nz-tab nzTitle="Tab Eagerly 2">
  11. <nz-demo-tab-content-eagerly></nz-demo-tab-content-eagerly>
  12. </nz-tab>
  13. <nz-tab nzTitle="Tab Lazy 1">
  14. <ng-template nz-tab>
  15. <nz-demo-tab-content-lazy></nz-demo-tab-content-lazy>
  16. </ng-template>
  17. </nz-tab>
  18. <nz-tab nzTitle="Tab Lazy 2">
  19. <ng-template nz-tab>
  20. <nz-demo-tab-content-lazy></nz-demo-tab-content-lazy>
  21. </ng-template>
  22. </nz-tab>
  23. </nz-tabset>
  24. `
  25. })
  26. export class NzDemoTabsLazyComponent {}
  27. @Component({
  28. selector: 'nz-demo-tab-content-lazy',
  29. template: `
  30. lazy
  31. `
  32. })
  33. export class NzDemoTabContentLazyComponent implements OnInit {
  34. ngOnInit(): void {
  35. console.log(`I will init when tab active`);
  36. }
  37. }
  38. @Component({
  39. selector: 'nz-demo-tab-content-eagerly',
  40. template: `
  41. eagerly
  42. `
  43. })
  44. export class NzDemoTabContentEagerlyComponent implements OnInit {
  45. ngOnInit(): void {
  46. console.log(`I will init eagerly`);
  47. }
  48. }

Tabs标签页 - 图15

路由联动

与路由联动,点击 tab 更改路由,并且在路由改变时自动切换 tab。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'nz-demo-tabs-link-router',
  4. template: `
  5. <nz-tabset nzLinkRouter>
  6. <nz-tab>
  7. <a *nzTabLink nz-tab-link [routerLink]="['.']" [queryParams]="{ tab: 'one' }" queryParamsHandling="merge">Default</a>
  8. Default.
  9. </nz-tab>
  10. <nz-tab>
  11. <a *nzTabLink nz-tab-link [routerLink]="['.']" [queryParams]="{ tab: 'two' }" queryParamsHandling="merge">Two</a>
  12. Two.
  13. </nz-tab>
  14. <nz-tab>
  15. <a *nzTabLink nz-tab-link [routerLink]="['.']" [queryParams]="{ tab: 'three' }" queryParamsHandling="merge">Three</a>
  16. Three.
  17. </nz-tab>
  18. <nz-tab>
  19. <a *nzTabLink nz-tab-link [routerLink]="['.']" [queryParams]="{ tab: 'four' }" queryParamsHandling="merge">Four</a>
  20. Four.
  21. </nz-tab>
  22. </nz-tabset>
  23. `
  24. })
  25. export class NzDemoTabsLinkRouterComponent {}

Tabs标签页 - 图16

标签守卫

通过 nzCanDeactivate 决定一个 tab 是否可以被切换。

  1. import { ChangeDetectionStrategy, Component } from '@angular/core';
  2. import { NzModalService } from 'ng-zorro-antd/modal';
  3. import { NzTabsCanDeactivateFn } from 'ng-zorro-antd/tabs';
  4. import { Observable } from 'rxjs';
  5. @Component({
  6. selector: 'nz-demo-tabs-guard',
  7. template: `
  8. <nz-tabset [nzCanDeactivate]="canDeactivate">
  9. <nz-tab *ngFor="let tab of tabs" [nzTitle]="'Tab' + tab">Content of tab {{ tab }}</nz-tab>
  10. </nz-tabset>
  11. `,
  12. changeDetection: ChangeDetectionStrategy.OnPush
  13. })
  14. export class NzDemoTabsGuardComponent {
  15. tabs = [1, 2, 3, 4];
  16. constructor(private modal: NzModalService) {}
  17. canDeactivate: NzTabsCanDeactivateFn = (fromIndex: number, toIndex: number) => {
  18. switch (fromIndex) {
  19. case 0:
  20. return toIndex === 1;
  21. case 1:
  22. return Promise.resolve(toIndex === 2);
  23. case 2:
  24. return this.confirm();
  25. default:
  26. return true;
  27. }
  28. };
  29. private confirm(): Observable<boolean> {
  30. return new Observable(observer => {
  31. this.modal.confirm({
  32. nzTitle: 'Are you sure you want to leave this tab?',
  33. nzOnOk: () => {
  34. observer.next(true);
  35. observer.complete();
  36. },
  37. nzOnCancel: () => {
  38. observer.next(false);
  39. observer.complete();
  40. }
  41. });
  42. });
  43. }
  44. }

API

nz-tabsetcomponent

参数说明类型默认值全局配置
[nzSelectedIndex]当前激活 tab 面板的 序列号,可双向绑定number-
[nzAnimated]是否使用动画切换 Tabs,在 nzTabPosition=top | bottom 时有效boolean | {inkBar:boolean, tabPane:boolean}true, 当 type=”card” 时为 false
[nzSize]大小,提供 largedefaultsmall 三种大小‘large’ | ‘small’ | ‘default’‘default’
[nzTabBarExtraContent]tab bar 上额外的元素TemplateRef<void>-
[nzTabBarStyle]tab bar 的样式对象object-
[nzTabPosition]页签位置,可选值有 toprightbottomleft‘top’ | ‘right’ | ‘bottom’ | ‘left’‘top’
[nzType]页签的基本样式‘line’ | ‘card’ | ‘editable-card’‘line’
[nzTabBarGutter]tabs 之间的间隙number-
[nzHideAll]是否隐藏所有tab内容booleanfalse
[nzLinkRouter]与 Angular 路由联动booleanfalse
[nzLinkExact]以严格匹配模式确定联动的路由booleantrue
[nzCanDeactivate]决定一个 tab 是否可以被切换NzTabsCanDeactivateFn-
[nzCentered]标签居中展示booleanfalse
(nzSelectedIndexChange)当前激活 tab 面板的 序列号变更回调函数EventEmitter<number>-
(nzSelectChange)当前激活 tab 面板变更回调函数EventEmitter<{index: number,tab: NzTabComponent}>-

nz-tabset[nzType=”editable-card”]component

参数说明类型默认值全局配置
[nzHideAdd]隐藏添加按钮booleanfalse
[nzAddIcon]添加按钮图标string | TemplateRef<void>-
(nzAdd)点击添加按钮时的事件EventEmitter<>-
(nzClose)点击删除按钮时的事件EventEmitter<{ index: number }>-

nz-tabcomponent

参数说明类型默认值
[nzTitle]选项卡头显示文字string | TemplateRef<TabTemplateContext>-
[nzForceRender]被隐藏时是否渲染 DOM 结构booleanfalse
[nzDisabled]是否禁用boolean-
(nzClick)单击 title 的回调函数EventEmitter<void>-
(nzContextmenu)右键 title 的回调函数EventEmitter<MouseEvent>-
(nzSelect)tab 被选中的回调函数EventEmitter<void>-
(nzDeselect)tab 被取消选中的回调函数EventEmitter<void>-

nz-tabset[nzType=”editable-card”] > nz-tabcomponent

参数说明类型默认值全局配置
[nzClosable]显示删除按钮booleanfalse
[nzCloseIcon]关闭按钮图标string | TemplateRef<void>-

nz-tab[nzTitle] 的模版引用变量

属性说明类型
visible表示是否在可见区域, 为 false 时将会被渲染到下拉菜单中boolean

nz-tab[nzTitle] 中使用

  1. <nz-tab [nzTitle]="titleTemplate">
  2. ...
  3. <ng-template #titleTemplate let-visible="visible">...</ng-template>
  4. </nz-tab>

*nzTabLink 中使用

  1. <nz-tab>
  2. <a *nzTabLink="let visible = visible" nz-tab-link [routerLink]="['.']">...</a>
  3. </nz-tab>

[nz-tab]directive

ng-template 一同使用,用于标记需要懒加载的 tab 内容,具体用法见示例。

ng-template[nzTabLink] > a[nz-tab-link]

路由联动可以让 tab 的切换和路由行为相一致。

  1. <nz-tabset nzLinkRouter>
  2. <nz-tab>
  3. <a *nzTabLink nz-tab-link [routerLink]="['.']">Link</a>
  4. Default.
  5. </nz-tab>
  6. </nz-tabset>