Drawer抽屉
屏幕边缘滑出的浮层面板。
何时使用
抽屉从父窗体边缘滑入,覆盖住部分父窗体内容。用户在抽屉内操作时不必离开当前任务,操作完成后,可以平滑地回到到原任务。
当需要一个附加的面板来控制父窗体内容,这个面板在需要时呼出。比如,控制界面展示样式,往界面中添加内容。
当需要在当前任务流中插入临时任务,创建或预览附加内容。比如展示协议条款,创建子对象。
代码演示

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

import React, { useState } from 'react';import { Drawer, Button } from 'antd';const App: React.FC = () => {const [visible, setVisible] = useState(false);const showDrawer = () => {setVisible(true);};const onClose = () => {setVisible(false);};return (<><Button type="primary" onClick={showDrawer}>Open</Button><Drawertitle="Basic Drawer"placement="right"closable={false}onClose={onClose}visible={visible}><p>Some contents...</p><p>Some contents...</p><p>Some contents...</p></Drawer></>);};ReactDOM.render(<App />, mountNode);

渲染在当前 dom 里。自定义容器,查看 getContainer。
import { Drawer, Button } from 'antd';class App extends React.Component {state = { visible: false };showDrawer = () => {this.setState({visible: true,});};onClose = () => {this.setState({visible: false,});};render() {return (<div className="site-drawer-render-in-current-wrapper">Render in this<div style={{ marginTop: 16 }}><Button type="primary" onClick={this.showDrawer}>Open</Button></div><Drawertitle="Basic Drawer"placement="right"closable={false}onClose={this.onClose}visible={this.state.visible}getContainer={false}style={{ position: 'absolute' }}><p>Some contents...</p></Drawer></div>);}}ReactDOM.render(<App />, mountNode);
.site-drawer-render-in-current-wrapper {position: relative;height: 200px;padding: 48px;overflow: hidden;text-align: center;background: #fafafa;border: 1px solid #ebedf0;border-radius: 2px;}

需要快速预览对象概要时使用,点击遮罩区关闭。
import { Drawer, List, Avatar, Divider, Col, Row } from 'antd';const DescriptionItem = ({ title, content }) => (<div className="site-description-item-profile-wrapper"><p className="site-description-item-profile-p-label">{title}:</p>{content}</div>);class App extends React.Component {state = { visible: false };showDrawer = () => {this.setState({visible: true,});};onClose = () => {this.setState({visible: false,});};render() {return (<><ListdataSource={[{name: 'Lily',},{name: 'Lily',},]}borderedrenderItem={item => (<List.Itemkey={item.id}actions={[<a onClick={this.showDrawer} key={`a-${item.id}`}>View Profile</a>,]}><List.Item.Metaavatar={<Avatar src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png" />}title={<a href="https://ant.design/index-cn">{item.name}</a>}description="Progresser XTech"/></List.Item>)}/><Drawerwidth={640}placement="right"closable={false}onClose={this.onClose}visible={this.state.visible}><p className="site-description-item-profile-p" style={{ marginBottom: 24 }}>User Profile</p><p className="site-description-item-profile-p">Personal</p><Row><Col span={12}><DescriptionItem title="Full Name" content="Lily" /></Col><Col span={12}><DescriptionItem title="Account" content="AntDesign@example.com" /></Col></Row><Row><Col span={12}><DescriptionItem title="City" content="HangZhou" /></Col><Col span={12}><DescriptionItem title="Country" content="China🇨🇳" /></Col></Row><Row><Col span={12}><DescriptionItem title="Birthday" content="February 2,1900" /></Col><Col span={12}><DescriptionItem title="Website" content="-" /></Col></Row><Row><Col span={24}><DescriptionItemtitle="Message"content="Make things as simple as possible but no simpler."/></Col></Row><Divider /><p className="site-description-item-profile-p">Company</p><Row><Col span={12}><DescriptionItem title="Position" content="Programmer" /></Col><Col span={12}><DescriptionItem title="Responsibilities" content="Coding" /></Col></Row><Row><Col span={12}><DescriptionItem title="Department" content="XTech" /></Col><Col span={12}><DescriptionItem title="Supervisor" content={<a>Lin</a>} /></Col></Row><Row><Col span={24}><DescriptionItemtitle="Skills"content="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."/></Col></Row><Divider /><p className="site-description-item-profile-p">Contacts</p><Row><Col span={12}><DescriptionItem title="Email" content="AntDesign@example.com" /></Col><Col span={12}><DescriptionItem title="Phone Number" content="+86 181 0000 0000" /></Col></Row><Row><Col span={24}><DescriptionItemtitle="Github"content={<a href="http://github.com/ant-design/ant-design/">github.com/ant-design/ant-design/</a>}/></Col></Row></Drawer></>);}}ReactDOM.render(<App />, mountNode);
.site-description-item-profile-wrapper {margin-bottom: 7px;color: rgba(0, 0, 0, 0.65);font-size: 14px;line-height: 1.5715;}[data-theme='compact'] .site-description-item-profile-wrapper {font-size: 12px;line-height: 1.66667;}.ant-drawer-body p.site-description-item-profile-p {display: block;margin-bottom: 16px;color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.5715;}[data-theme='compact'] .ant-drawer-body p.site-description-item-profile-p {font-size: 14px;line-height: 1.66667;}.site-description-item-profile-p-label {display: inline-block;margin-right: 8px;color: rgba(0, 0, 0, 0.85);}

自定义位置,点击触发按钮抽屉从相应的位置滑出,点击遮罩区关闭
import { Drawer, Button, Radio, Space } from 'antd';class App extends React.Component {state = { visible: false, placement: 'left' };showDrawer = () => {this.setState({visible: true,});};onClose = () => {this.setState({visible: false,});};onChange = e => {this.setState({placement: e.target.value,});};render() {const { placement, visible } = this.state;return (<><Space><Radio.Group defaultValue={placement} onChange={this.onChange}><Radio value="top">top</Radio><Radio value="right">right</Radio><Radio value="bottom">bottom</Radio><Radio value="left">left</Radio></Radio.Group><Button type="primary" onClick={this.showDrawer}>Open</Button></Space><Drawertitle="Basic Drawer"placement={placement}closable={false}onClose={this.onClose}visible={visible}key={placement}><p>Some contents...</p><p>Some contents...</p><p>Some contents...</p></Drawer></>);}}ReactDOM.render(<App />, mountNode);

在抽屉中使用表单。
import { Drawer, Form, Button, Col, Row, Input, Select, DatePicker } from 'antd';import { PlusOutlined } from '@ant-design/icons';const { Option } = Select;class DrawerForm extends React.Component {state = { visible: false };showDrawer = () => {this.setState({visible: true,});};onClose = () => {this.setState({visible: false,});};render() {return (<><Button type="primary" onClick={this.showDrawer}><PlusOutlined /> New account</Button><Drawertitle="Create a new account"width={720}onClose={this.onClose}visible={this.state.visible}bodyStyle={{ paddingBottom: 80 }}footer={<divstyle={{textAlign: 'right',}}><Button onClick={this.onClose} style={{ marginRight: 8 }}>Cancel</Button><Button onClick={this.onClose} type="primary">Submit</Button></div>}><Form layout="vertical" hideRequiredMark><Row gutter={16}><Col span={12}><Form.Itemname="name"label="Name"rules={[{ required: true, message: 'Please enter user name' }]}><Input placeholder="Please enter user name" /></Form.Item></Col><Col span={12}><Form.Itemname="url"label="Url"rules={[{ required: true, message: 'Please enter url' }]}><Inputstyle={{ width: '100%' }}addonBefore="http://"addonAfter=".com"placeholder="Please enter url"/></Form.Item></Col></Row><Row gutter={16}><Col span={12}><Form.Itemname="owner"label="Owner"rules={[{ required: true, message: 'Please select an owner' }]}><Select placeholder="Please select an owner"><Option value="xiao">Xiaoxiao Fu</Option><Option value="mao">Maomao Zhou</Option></Select></Form.Item></Col><Col span={12}><Form.Itemname="type"label="Type"rules={[{ required: true, message: 'Please choose the type' }]}><Select placeholder="Please choose the type"><Option value="private">Private</Option><Option value="public">Public</Option></Select></Form.Item></Col></Row><Row gutter={16}><Col span={12}><Form.Itemname="approver"label="Approver"rules={[{ required: true, message: 'Please choose the approver' }]}><Select placeholder="Please choose the approver"><Option value="jack">Jack Ma</Option><Option value="tom">Tom Liu</Option></Select></Form.Item></Col><Col span={12}><Form.Itemname="dateTime"label="DateTime"rules={[{ required: true, message: 'Please choose the dateTime' }]}><DatePicker.RangePickerstyle={{ width: '100%' }}getPopupContainer={trigger => trigger.parentElement}/></Form.Item></Col></Row><Row gutter={16}><Col span={24}><Form.Itemname="description"label="Description"rules={[{required: true,message: 'please enter url description',},]}><Input.TextArea rows={4} placeholder="please enter url description" /></Form.Item></Col></Row></Form></Drawer></>);}}ReactDOM.render(<DrawerForm />, mountNode);
.site-form-in-drawer-wrapper {position: absolute;right: 0px;bottom: 0px;width: 100%;padding: 10px 16px;border-top: 1px solid #e9e9e9;background: #fff;text-align: right;}

在抽屉内打开新的抽屉,用以解决多分支任务的复杂状况。
import { Drawer, Button } from 'antd';class App extends React.Component {state = { visible: false, childrenDrawer: false };showDrawer = () => {this.setState({visible: true,});};onClose = () => {this.setState({visible: false,});};showChildrenDrawer = () => {this.setState({childrenDrawer: true,});};onChildrenDrawerClose = () => {this.setState({childrenDrawer: false,});};render() {return (<><Button type="primary" onClick={this.showDrawer}>Open drawer</Button><Drawertitle="Multi-level drawer"width={520}closable={false}onClose={this.onClose}visible={this.state.visible}><Button type="primary" onClick={this.showChildrenDrawer}>Two-level drawer</Button><Drawertitle="Two-level Drawer"width={320}closable={false}onClose={this.onChildrenDrawerClose}visible={this.state.childrenDrawer}>This is two-level drawer</Drawer></Drawer></>);}}ReactDOM.render(<App />, mountNode);
API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
| afterVisibleChange | 切换抽屉时动画结束后的回调 | function(visible) | - | |
| bodyStyle | 可用于设置 Drawer 内容部分的样式 | CSSProperties | - | |
| className | 对话框外层容器的类名 | string | - | |
| closable | 是否显示右上角的关闭按钮 | boolean | true | |
| closeIcon | 自定义关闭图标 | ReactNode | <CloseOutlined /> | |
| destroyOnClose | 关闭时销毁 Drawer 里的子元素 | boolean | false | |
| drawerStyle | 用于设置 Drawer 弹出层的样式 | CSSProperties | - | |
| footer | 抽屉的页脚 | ReactNode | - | |
| footerStyle | 抽屉页脚部件的样式 | CSSProperties | - | |
| forceRender | 预渲染 Drawer 内元素 | boolean | false | |
| getContainer | 指定 Drawer 挂载的 HTML 节点, false 为挂载在当前 dom | HTMLElement | () => HTMLElement | Selectors | false | body | |
| headerStyle | 用于设置 Drawer 头部的样式 | CSSProperties | - | |
| height | 高度, 在 placement 为 top 或 bottom 时使用 | string | number | 256 | |
| keyboard | 是否支持键盘 esc 关闭 | boolean | true | |
| mask | 是否展示遮罩 | boolean | true | |
| maskClosable | 点击蒙层是否允许关闭 | boolean | true | |
| maskStyle | 遮罩样式 | CSSProperties | {} | |
| placement | 抽屉的方向 | top | right | bottom | left | right | |
| push | 用于设置多层 Drawer 的推动行为 | boolean | { distance: string | number } | { distance: 180 } | 4.5.0+ |
| style | 可用于设置 Drawer 最外层容器的样式,和 drawerStyle 的区别是作用节点包括 mask | CSSProperties | - | |
| title | 标题 | ReactNode | - | |
| visible | Drawer 是否可见 | boolean | - | |
| width | 宽度 | string | number | 256 | |
| zIndex | 设置 Drawer 的 z-index | number | 1000 | |
| onClose | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | - |