Drawer抽屉

抽屉从父窗体边缘滑入,覆盖住部分父窗体内容。用户在抽屉内操作时不必离开当前任务,操作完成后,可以平滑地回到到原任务。

何时使用#

  • 当需要一个附加的面板来控制父窗体内容,这个面板在需要时呼出。比如,控制界面展示样式,往界面中添加内容。
  • 当需要在当前任务流中插入临时任务,创建或预览附加内容。比如展示协议条款,创建子对象。

单独引入此组件#

想要了解更多关于单独引入组件的内容,可以在快速上手页面进行查看。

import { NzDrawerModule } from 'ng-zorro-antd/drawer';

代码演示

基础抽屉,点击触发按钮抽屉从右滑出,点击遮罩区关闭

expand codeexpand code
import { Component } from '@angular/core';

@Component({
  selector: 'nz-demo-drawer-basic-right',
  template: `
    <button nz-button nzType="primary" (click)="open()">Open</button>
    <nz-drawer
      [nzClosable]="false"
      [nzVisible]="visible"
      nzPlacement="right"
      nzTitle="Basic Drawer"
      (nzOnClose)="close()"
    >
      <p>Some contents...</p>
      <p>Some contents...</p>
      <p>Some contents...</p>
    </nz-drawer>
  `
})
export class NzDemoDrawerBasicRightComponent {
  visible = false;

  open(): void {
    this.visible = true;
  }

  close(): void {
    this.visible = false;
  }
}

用于承载编辑相关操作,需要点击关闭按钮关闭。

expand codeexpand code
import { Component } from '@angular/core';

@Component({
  selector: 'nz-demo-drawer-from-drawer',
  template: `
    <button nz-button nzType="primary" (click)="open()">Create</button>
    <nz-drawer
      [nzBodyStyle]="{ height: 'calc(100% - 55px)', overflow: 'auto', 'padding-bottom': '53px' }"
      [nzMaskClosable]="false"
      [nzWidth]="720"
      [nzVisible]="visible"
      nzTitle="Create"
      (nzOnClose)="close()"
    >
      <form nz-form>
        <div nz-row nzGutter="8">
          <div nz-col nzSpan="12">
            <nz-form-item>
              <nz-form-label>Name</nz-form-label>
              <nz-form-control>
                <input nz-input placeholder="please enter user name" />
              </nz-form-control>
            </nz-form-item>
          </div>
          <div nz-col nzSpan="12">
            <nz-form-item>
              <nz-form-label>Url</nz-form-label>
              <nz-form-control>
                <nz-input-group nzAddOnBefore="http://" nzAddOnAfter=".com">
                  <input type="text" nz-input placeholder="please enter url" />
                </nz-input-group>
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
        <div nz-row nzGutter="8">
          <div nz-col nzSpan="12">
            <nz-form-item>
              <nz-form-label>Owner</nz-form-label>
              <nz-form-control>
                <nz-select nzPlaceHolder="Please select an owner"></nz-select>
              </nz-form-control>
            </nz-form-item>
          </div>
          <div nz-col nzSpan="12">
            <nz-form-item>
              <nz-form-label>Type</nz-form-label>
              <nz-form-control>
                <nz-select nzPlaceHolder="Please choose the type"></nz-select>
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
        <div nz-row nzGutter="8">
          <div nz-col nzSpan="12">
            <nz-form-item>
              <nz-form-label>Approver</nz-form-label>
              <nz-form-control>
                <nz-select nzPlaceHolder="Please choose the approver"></nz-select>
              </nz-form-control>
            </nz-form-item>
          </div>
          <div nz-col nzSpan="12">
            <nz-form-item>
              <nz-form-label>DateTime</nz-form-label>
              <nz-form-control>
                <nz-range-picker></nz-range-picker>
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
        <div nz-row nzGutter="8">
          <div nz-col nzSpan="24">
            <nz-form-item>
              <nz-form-label>Description</nz-form-label>
              <nz-form-control>
                <textarea
                  nz-input
                  placeholder="please enter url description"
                  [nzAutosize]="{ minRows: 4, maxRows: 4 }"
                ></textarea>
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
      </form>
      <div class="footer">
        <button type="button" (click)="close()" class="ant-btn" style="margin-right: 8px;"><span>Cancel</span></button>
        <button type="button" (click)="close()" class="ant-btn ant-btn-primary"><span>Submit</span></button>
      </div>
    </nz-drawer>
  `,
  styles: [
    `
      .footer {
        position: absolute;
        bottom: 0px;
        width: 100%;
        border-top: 1px solid rgb(232, 232, 232);
        padding: 10px 16px;
        text-align: right;
        left: 0px;
        background: #fff;
      }
    `
  ]
})
export class NzDemoDrawerFromDrawerComponent {
  visible = false;

  open(): void {
    this.visible = true;
  }

  close(): void {
    this.visible = false;
  }
}

在抽屉内打开新的抽屉,用以解决多分支任务的复杂状况。

expand codeexpand code
import { Component } from '@angular/core';

@Component({
  selector: 'nz-demo-drawer-multi-level-drawer',
  template: `
    <button nz-button nzType="primary" (click)="open()">New Cookbook</button>
    <nz-drawer
      [nzClosable]="false"
      [nzOffsetX]="childrenVisible ? 180 : 0"
      [nzWidth]="320"
      [nzVisible]="visible"
      nzTitle="Cookbook"
      (nzOnClose)="close()"
    >
      <form nz-form>
        <div nz-row>
          <div nz-col nzSpan="24">
            <nz-form-item>
              <nz-form-label>Name</nz-form-label>
              <nz-form-control>
                <input nz-input placeholder="please enter cookbook name" />
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
        <div nz-row>
          <div nz-col nzSpan="24">
            <nz-form-item>
              <nz-form-label>Food</nz-form-label>
              <nz-form-control>
                <nz-tag>potato</nz-tag>
                <nz-tag>eggplant</nz-tag>
                <nz-tag (click)="openChildren()">+</nz-tag>
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
      </form>
      <div class="footer">
        <button type="button" (click)="close()" class="ant-btn" style="margin-right: 8px;"><span>Cancel</span></button>
        <button type="button" (click)="close()" class="ant-btn ant-btn-primary"><span>Submit</span></button>
      </div>
      <nz-drawer [nzClosable]="false" [nzVisible]="childrenVisible" nzTitle="Food" (nzOnClose)="closeChildren()">
        <nz-list [nzDataSource]="vegetables" [nzRenderItem]="item">
          <ng-template #item let-item>
            <nz-list-item [nzContent]="item"></nz-list-item>
          </ng-template>
        </nz-list>
      </nz-drawer>
    </nz-drawer>
  `,
  styles: [
    `
      .footer {
        position: absolute;
        bottom: 0px;
        width: 100%;
        border-top: 1px solid rgb(232, 232, 232);
        padding: 10px 16px;
        text-align: right;
        left: 0px;
        background: #fff;
      }
    `
  ]
})
export class NzDemoDrawerMultiLevelDrawerComponent {
  visible = false;
  childrenVisible = false;

  vegetables = ['asparagus', 'bamboo', 'potato', 'carrot', 'cilantro', 'potato', 'eggplant'];

  open(): void {
    this.visible = true;
  }

  close(): void {
    this.visible = false;
  }

  openChildren(): void {
    this.childrenVisible = true;
  }

  closeChildren(): void {
    this.childrenVisible = false;
  }
}

自定义位置,点击触发按钮抽屉从相应的位置滑出,点击遮罩区关闭

expand codeexpand code
import { Component } from '@angular/core';

@Component({
  selector: 'nz-demo-drawer-placement',
  template: `
    <nz-radio-group [(ngModel)]="placement">
      <label nz-radio nzValue="top">top</label>
      <label nz-radio nzValue="right">right</label>
      <label nz-radio nzValue="bottom">bottom</label>
      <label nz-radio nzValue="left">left</label>
    </nz-radio-group>
    <button nz-button nzType="primary" (click)="open()">Open</button>
    <nz-drawer
      [nzClosable]="false"
      [nzVisible]="visible"
      [nzPlacement]="placement"
      nzTitle="Basic Drawer"
      (nzOnClose)="close()"
    >
      <p>Some contents...</p>
      <p>Some contents...</p>
      <p>Some contents...</p>
    </nz-drawer>
  `
})
export class NzDemoDrawerPlacementComponent {
  visible = false;
  placement = 'left';
  open(): void {
    this.visible = true;
  }

  close(): void {
    this.visible = false;
  }
}

Lily

Progresser AFX

Lily

Progresser AFX

需要快速预览对象概要时使用,点击遮罩区关闭。

expand codeexpand code
import { Component } from '@angular/core';

@Component({
  selector: 'nz-demo-drawer-user-profile',
  template: `
    <nz-list [nzDataSource]="data" [nzRenderItem]="item" [nzItemLayout]="'horizontal'">
      <ng-template #item let-item>
        <nz-list-item [nzActions]="[viewAction]">
          <ng-template #viewAction>
            <a (click)="open()">View Profile</a>
          </ng-template>
          <nz-list-item-meta
            [nzTitle]="nzTitle"
            nzAvatar="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png"
            nzDescription="Progresser AFX"
          >
            <ng-template #nzTitle>
              <a href="https://ng.ant.design">{{ item.name }}</a>
            </ng-template>
          </nz-list-item-meta>
        </nz-list-item>
      </ng-template>
    </nz-list>
    <nz-drawer [nzVisible]="visible" [nzWidth]="640" [nzClosable]="false" (nzOnClose)="close()">
      <p class="title" style=" margin-bottom: 24px;">User Profile</p>
      <p class="title">Personal</p>
      <div nz-row>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Full Name:</p>
            Lily
          </div>
        </div>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Account:</p>
            AntDesign@example.com
          </div>
        </div>
      </div>
      <div nz-row>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">City:</p>
            HangZhou
          </div>
        </div>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Country:</p>
            China🇨🇳
          </div>
        </div>
      </div>
      <div nz-row>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Birthday:</p>
            February 2,1900
          </div>
        </div>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Website:</p>
            -
          </div>
        </div>
      </div>
      <div nz-row>
        <div nz-col nzSpan="24">
          <div class="item-wrap">
            <p class="label">Message:</p>
            Make things as simple as possible but no simpler.
          </div>
        </div>
      </div>
      <nz-divider></nz-divider>
      <p class="title">Company</p>
      <div nz-row>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Position:</p>
            Programmer
          </div>
        </div>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Responsibilities:</p>
            Coding
          </div>
        </div>
      </div>
      <div nz-row>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Department:</p>
            AFX
          </div>
        </div>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Supervisor:</p>
            <a>Lin</a>
          </div>
        </div>
      </div>
      <div nz-row>
        <div nz-col nzSpan="24">
          <div class="item-wrap">
            <p class="label">Skills:</p>
            C / C + +, data structures, software engineering, operating systems, computer networks, databases, compiler
            theory, computer architecture, Microcomputer Principle and Interface Technology, Computer English, Java,
            ASP, etc.
          </div>
        </div>
      </div>
      <nz-divider></nz-divider>
      <p class="title">Contacts</p>
      <div nz-row>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Email:</p>
            AntDesign@example.com
          </div>
        </div>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Phone Number:</p>
            +86 181 0000 0000
          </div>
        </div>
      </div>
      <div nz-row>
        <div nz-col nzSpan="24">
          <div class="item-wrap">
            <p class="label">Github:</p>
            <a href="https://github.com/NG-ZORRO/ng-zorro-antd" target="_blank">github.com/NG-ZORRO/ng-zorro-antd</a>
          </div>
        </div>
      </div>
    </nz-drawer>
  `,
  styles: [
    `
      .title {
        font-size: 16px;
        color: rgba(0, 0, 0, 0.85);
        line-height: 24px;
        display: block;
        margin-bottom: 16px;
      }
      .item-wrap {
        font-size: 14px;
        line-height: 22px;
        margin-bottom: 7px;
        color: rgba(0, 0, 0, 0.65);
      }
      .label {
        margin-right: 8px;
        display: inline-block;
        color: rgba(0, 0, 0, 0.85);
      }
    `
  ]
})
export class NzDemoDrawerUserProfileComponent {
  data = [
    {
      name: 'Lily'
    },
    {
      name: 'Lily'
    }
  ];

  visible = false;

  open(): void {
    this.visible = true;
  }

  close(): void {
    this.visible = false;
  }
}
 

Drawer 的 service 用法,示例中演示了用户自定义模板、自定义component。

注意 如果使用Component模式,则需要在NgModule中的 declarationsentryComponents 加入自定义的Component

expand codeexpand code
/* entryComponents: NzDrawerCustomComponent */

import { Component, Input, TemplateRef, ViewChild } from '@angular/core';
import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd';

@Component({
  selector: 'nz-demo-drawer-service',
  template: `
    <ng-template #drawerTemplate let-data let-drawerRef="drawerRef">
      value: {{ data?.value }}
      <br />
      <button nz-button nzType="primary" (click)="drawerRef.close()">close</button>
    </ng-template>
    <div nz-form>
      <nz-form-item>
        <input nz-input [(ngModel)]="value" />
      </nz-form-item>
    </div>
    <button nz-button nzType="primary" (click)="openTemplate()">Use Template</button>&nbsp;
    <button nz-button nzType="primary" (click)="openComponent()">Use Component</button>
  `
})
export class NzDemoDrawerServiceComponent {
  @ViewChild('drawerTemplate', { static: false }) drawerTemplate: TemplateRef<{
    $implicit: { value: string };
    drawerRef: NzDrawerRef<any>;
  }>;
  value = 'ng';

  constructor(private drawerService: NzDrawerService) {}

  openTemplate(): void {
    const drawerRef = this.drawerService.create({
      nzTitle: 'Template',
      nzContent: this.drawerTemplate,
      nzContentParams: {
        value: this.value
      }
    });

    drawerRef.afterOpen.subscribe(() => {
      console.log('Drawer(Template) open');
    });

    drawerRef.afterClose.subscribe(() => {
      console.log('Drawer(Template) close');
    });
  }

  openComponent(): void {
    const drawerRef = this.drawerService.create<NzDrawerCustomComponent, { value: string }, string>({
      nzTitle: 'Component',
      nzContent: NzDrawerCustomComponent,
      nzContentParams: {
        value: this.value
      }
    });

    drawerRef.afterOpen.subscribe(() => {
      console.log('Drawer(Component) open');
    });

    drawerRef.afterClose.subscribe(data => {
      console.log(data);
      if (typeof data === 'string') {
        this.value = data;
      }
    });
  }
}

@Component({
  selector: 'nz-drawer-custom-component',
  template: `
    <div>
      <input nz-input [(ngModel)]="value" />
      <nz-divider></nz-divider>
      <button nzType="primary" (click)="close()" nz-button>Confirm</button>
    </div>
  `
})
export class NzDrawerCustomComponent {
  @Input() value = '';

  constructor(private drawerRef: NzDrawerRef<string>) {}

  close(): void {
    this.drawerRef.close(this.value);
  }
}

API#

nz-drawer#

参数说明类型默认值
[nzClosable]是否显示右上角的关闭按钮booleantrue
[nzMaskClosable]点击蒙层是否允许关闭booleantrue
[nzMask]是否展示遮罩booleantrue
[nzMaskStyle]遮罩样式object{}
[nzBodyStyle]Drawer body 样式object{}
[nzTitle]标题string | TemplateRef<void>-
[nzVisible]Drawer 是否可见boolean-
[nzPlacement]抽屉的方向'top' | 'right' | 'bottom' | 'left''right'
[nzWidth]宽度, 只在方向为 'right''left' 时生效number | string256
[nzHeight]高度, 只在方向为 'top''bottom' 时生效number | string256
[nzOffsetX]x 坐标移量(px), 只在方向为 'right''left' 时生效number0
[nzOffsetY]y 坐标移量(px), 高度, 只在方向为 'top''bottom' 时生效number0
[nzWrapClassName]对话框外层容器的类名string-
[nzZIndex]设置 Drawer 的 z-indexnumber1000
(nzOnClose)点击遮罩层或右上角叉的回调EventEmitter<MouseEvent>-

NzDrawerService#

方法名说明参数返回
create创建并打开一个 DrawerNzDrawerOptions<T, D, R>NzDrawerRef<R>

NzDrawerOptions#

参数说明类型默认值
nzContentDrawer body 的内容TemplateRef<{ $implicit: D, drawerRef: NzDrawerRef }> | Type<T>-
nzContentParams内容组件的输入参数 / Template的 contextD-
nzOnCancel点击遮罩层或右上角叉时执行,该函数可返回 promise 待执行完毕或 promise 结束时,将自动关闭对话框(返回false可阻止关闭)() => Promise<any>-
nzClosable是否显示右上角的关闭按钮booleantrue
nzMaskClosable点击蒙层是否允许关闭booleantrue
nzMask是否展示遮罩booleantrue
nzMaskStyle遮罩样式object{}
nzBodyStyleModal body 样式object{}
nzTitle标题string | TemplateRef<void>-
nzWidth宽度number | string256
nzHeight高度, 只在方向为 'top''bottom' 时生效number | string256
nzWrapClassName对话框外层容器的类名string-
nzZIndex设置 Drawer 的 z-indexnumber1000
nzPlacement抽屉的方向'top' | 'right' | 'bottom' | 'left''right'
nzOffsetXx 坐标移量(px)number0
nzOffsetYy 坐标移量(px), 高度, 只在方向为 'top''bottom' 时生效number0

NzDrawerRef#

方法#

名称说明类型
close关闭 Drawer(result?: R) => void
open打开 Drawer() => void

属性#

名称说明类型
afterOpen打开之后的回调Observable<void>
afterClose关闭之后的回调Observable<R>
nzClosable是否显示右上角的关闭按钮booleantrue
nzMaskClosable点击蒙层是否允许关闭booleantrue
nzMask是否展示遮罩booleantrue
nzMaskStyle遮罩样式object{}
nzBodyStyleModal body 样式object{}
nzTitle标题string | TemplateRef<void>-
nzWidth宽度number | string256
nzHeight高度, 只在方向为 'top''bottom' 时生效number | string256
nzWrapClassName对话框外层容器的类名string-
nzZIndex设置 Drawer 的 z-indexnumber1000
nzPlacement抽屉的方向'top' | 'right' | 'bottom' | 'left''right'
nzOffsetXx 坐标移量(px)number0
nzOffsetYy 坐标移量(px), 高度, 只在方向为 'top''bottom' 时生效number0
Basic Drawer

Some contents...

Some contents...

Some contents...

Create
http://.com
Please select an owner
Please choose the type
Please choose the approver
~
Cookbook
potatoeggplant+
Food
asparagusbamboopotatocarrotcilantropotatoeggplant
Basic Drawer

Some contents...

Some contents...

Some contents...

User Profile

Personal

Full Name:

Lily

Account:

AntDesign@example.com

City:

HangZhou

Country:

China🇨🇳

Birthday:

February 2,1900

Website:

-

Message:

Make things as simple as possible but no simpler.

Company

Position:

Programmer

Responsibilities:

Coding

Department:

AFX

Supervisor:

Lin

Skills:

C / C + +, data structures, software engineering, operating systems, computer networks, databases, compiler theory, computer architecture, Microcomputer Principle and Interface Technology, Computer English, Java, ASP, etc.

Contacts

Email:

AntDesign@example.com

Phone Number:

+86 181 0000 0000