Drawer抽屉

屏幕边缘滑出的浮层面板。

何时使用

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

  • 当需要一个附加的面板来控制父窗体内容,这个面板在需要时呼出。比如,控制界面展示样式,往界面中添加内容。

  • 当需要在当前任务流中插入临时任务,创建或预览附加内容。比如展示协议条款,创建子对象。

代码演示

Drawer抽屉 - 图1

基础抽屉

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

TypeScript

JavaScript

Drawer抽屉 - 图2

  1. import React, { useState } from 'react';
  2. import { Drawer, Button } from 'antd';
  3. const App: React.FC = () => {
  4. const [visible, setVisible] = useState(false);
  5. const showDrawer = () => {
  6. setVisible(true);
  7. };
  8. const onClose = () => {
  9. setVisible(false);
  10. };
  11. return (
  12. <>
  13. <Button type="primary" onClick={showDrawer}>
  14. Open
  15. </Button>
  16. <Drawer
  17. title="Basic Drawer"
  18. placement="right"
  19. closable={false}
  20. onClose={onClose}
  21. visible={visible}
  22. >
  23. <p>Some contents...</p>
  24. <p>Some contents...</p>
  25. <p>Some contents...</p>
  26. </Drawer>
  27. </>
  28. );
  29. };
  30. ReactDOM.render(<App />, mountNode);

Drawer抽屉 - 图3

渲染在当前 DOM

渲染在当前 dom 里。自定义容器,查看 getContainer。

  1. import { Drawer, Button } from 'antd';
  2. class App extends React.Component {
  3. state = { visible: false };
  4. showDrawer = () => {
  5. this.setState({
  6. visible: true,
  7. });
  8. };
  9. onClose = () => {
  10. this.setState({
  11. visible: false,
  12. });
  13. };
  14. render() {
  15. return (
  16. <div className="site-drawer-render-in-current-wrapper">
  17. Render in this
  18. <div style={{ marginTop: 16 }}>
  19. <Button type="primary" onClick={this.showDrawer}>
  20. Open
  21. </Button>
  22. </div>
  23. <Drawer
  24. title="Basic Drawer"
  25. placement="right"
  26. closable={false}
  27. onClose={this.onClose}
  28. visible={this.state.visible}
  29. getContainer={false}
  30. style={{ position: 'absolute' }}
  31. >
  32. <p>Some contents...</p>
  33. </Drawer>
  34. </div>
  35. );
  36. }
  37. }
  38. ReactDOM.render(<App />, mountNode);
  1. .site-drawer-render-in-current-wrapper {
  2. position: relative;
  3. height: 200px;
  4. padding: 48px;
  5. overflow: hidden;
  6. text-align: center;
  7. background: #fafafa;
  8. border: 1px solid #ebedf0;
  9. border-radius: 2px;
  10. }

Drawer抽屉 - 图4

信息预览抽屉

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

  1. import { Drawer, List, Avatar, Divider, Col, Row } from 'antd';
  2. const DescriptionItem = ({ title, content }) => (
  3. <div className="site-description-item-profile-wrapper">
  4. <p className="site-description-item-profile-p-label">{title}:</p>
  5. {content}
  6. </div>
  7. );
  8. class App extends React.Component {
  9. state = { visible: false };
  10. showDrawer = () => {
  11. this.setState({
  12. visible: true,
  13. });
  14. };
  15. onClose = () => {
  16. this.setState({
  17. visible: false,
  18. });
  19. };
  20. render() {
  21. return (
  22. <>
  23. <List
  24. dataSource={[
  25. {
  26. name: 'Lily',
  27. },
  28. {
  29. name: 'Lily',
  30. },
  31. ]}
  32. bordered
  33. renderItem={item => (
  34. <List.Item
  35. key={item.id}
  36. actions={[
  37. <a onClick={this.showDrawer} key={`a-${item.id}`}>
  38. View Profile
  39. </a>,
  40. ]}
  41. >
  42. <List.Item.Meta
  43. avatar={
  44. <Avatar src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png" />
  45. }
  46. title={<a href="https://ant.design/index-cn">{item.name}</a>}
  47. description="Progresser XTech"
  48. />
  49. </List.Item>
  50. )}
  51. />
  52. <Drawer
  53. width={640}
  54. placement="right"
  55. closable={false}
  56. onClose={this.onClose}
  57. visible={this.state.visible}
  58. >
  59. <p className="site-description-item-profile-p" style={{ marginBottom: 24 }}>
  60. User Profile
  61. </p>
  62. <p className="site-description-item-profile-p">Personal</p>
  63. <Row>
  64. <Col span={12}>
  65. <DescriptionItem title="Full Name" content="Lily" />
  66. </Col>
  67. <Col span={12}>
  68. <DescriptionItem title="Account" content="AntDesign@example.com" />
  69. </Col>
  70. </Row>
  71. <Row>
  72. <Col span={12}>
  73. <DescriptionItem title="City" content="HangZhou" />
  74. </Col>
  75. <Col span={12}>
  76. <DescriptionItem title="Country" content="China🇨🇳" />
  77. </Col>
  78. </Row>
  79. <Row>
  80. <Col span={12}>
  81. <DescriptionItem title="Birthday" content="February 2,1900" />
  82. </Col>
  83. <Col span={12}>
  84. <DescriptionItem title="Website" content="-" />
  85. </Col>
  86. </Row>
  87. <Row>
  88. <Col span={24}>
  89. <DescriptionItem
  90. title="Message"
  91. content="Make things as simple as possible but no simpler."
  92. />
  93. </Col>
  94. </Row>
  95. <Divider />
  96. <p className="site-description-item-profile-p">Company</p>
  97. <Row>
  98. <Col span={12}>
  99. <DescriptionItem title="Position" content="Programmer" />
  100. </Col>
  101. <Col span={12}>
  102. <DescriptionItem title="Responsibilities" content="Coding" />
  103. </Col>
  104. </Row>
  105. <Row>
  106. <Col span={12}>
  107. <DescriptionItem title="Department" content="XTech" />
  108. </Col>
  109. <Col span={12}>
  110. <DescriptionItem title="Supervisor" content={<a>Lin</a>} />
  111. </Col>
  112. </Row>
  113. <Row>
  114. <Col span={24}>
  115. <DescriptionItem
  116. title="Skills"
  117. 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."
  118. />
  119. </Col>
  120. </Row>
  121. <Divider />
  122. <p className="site-description-item-profile-p">Contacts</p>
  123. <Row>
  124. <Col span={12}>
  125. <DescriptionItem title="Email" content="AntDesign@example.com" />
  126. </Col>
  127. <Col span={12}>
  128. <DescriptionItem title="Phone Number" content="+86 181 0000 0000" />
  129. </Col>
  130. </Row>
  131. <Row>
  132. <Col span={24}>
  133. <DescriptionItem
  134. title="Github"
  135. content={
  136. <a href="http://github.com/ant-design/ant-design/">
  137. github.com/ant-design/ant-design/
  138. </a>
  139. }
  140. />
  141. </Col>
  142. </Row>
  143. </Drawer>
  144. </>
  145. );
  146. }
  147. }
  148. ReactDOM.render(<App />, mountNode);
  1. .site-description-item-profile-wrapper {
  2. margin-bottom: 7px;
  3. color: rgba(0, 0, 0, 0.65);
  4. font-size: 14px;
  5. line-height: 1.5715;
  6. }
  7. [data-theme='compact'] .site-description-item-profile-wrapper {
  8. font-size: 12px;
  9. line-height: 1.66667;
  10. }
  11. .ant-drawer-body p.site-description-item-profile-p {
  12. display: block;
  13. margin-bottom: 16px;
  14. color: rgba(0, 0, 0, 0.85);
  15. font-size: 16px;
  16. line-height: 1.5715;
  17. }
  18. [data-theme='compact'] .ant-drawer-body p.site-description-item-profile-p {
  19. font-size: 14px;
  20. line-height: 1.66667;
  21. }
  22. .site-description-item-profile-p-label {
  23. display: inline-block;
  24. margin-right: 8px;
  25. color: rgba(0, 0, 0, 0.85);
  26. }

Drawer抽屉 - 图5

自定义位置

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

  1. import { Drawer, Button, Radio, Space } from 'antd';
  2. class App extends React.Component {
  3. state = { visible: false, placement: 'left' };
  4. showDrawer = () => {
  5. this.setState({
  6. visible: true,
  7. });
  8. };
  9. onClose = () => {
  10. this.setState({
  11. visible: false,
  12. });
  13. };
  14. onChange = e => {
  15. this.setState({
  16. placement: e.target.value,
  17. });
  18. };
  19. render() {
  20. const { placement, visible } = this.state;
  21. return (
  22. <>
  23. <Space>
  24. <Radio.Group defaultValue={placement} onChange={this.onChange}>
  25. <Radio value="top">top</Radio>
  26. <Radio value="right">right</Radio>
  27. <Radio value="bottom">bottom</Radio>
  28. <Radio value="left">left</Radio>
  29. </Radio.Group>
  30. <Button type="primary" onClick={this.showDrawer}>
  31. Open
  32. </Button>
  33. </Space>
  34. <Drawer
  35. title="Basic Drawer"
  36. placement={placement}
  37. closable={false}
  38. onClose={this.onClose}
  39. visible={visible}
  40. key={placement}
  41. >
  42. <p>Some contents...</p>
  43. <p>Some contents...</p>
  44. <p>Some contents...</p>
  45. </Drawer>
  46. </>
  47. );
  48. }
  49. }
  50. ReactDOM.render(<App />, mountNode);

Drawer抽屉 - 图6

抽屉表单

在抽屉中使用表单。

  1. import { Drawer, Form, Button, Col, Row, Input, Select, DatePicker } from 'antd';
  2. import { PlusOutlined } from '@ant-design/icons';
  3. const { Option } = Select;
  4. class DrawerForm extends React.Component {
  5. state = { visible: false };
  6. showDrawer = () => {
  7. this.setState({
  8. visible: true,
  9. });
  10. };
  11. onClose = () => {
  12. this.setState({
  13. visible: false,
  14. });
  15. };
  16. render() {
  17. return (
  18. <>
  19. <Button type="primary" onClick={this.showDrawer}>
  20. <PlusOutlined /> New account
  21. </Button>
  22. <Drawer
  23. title="Create a new account"
  24. width={720}
  25. onClose={this.onClose}
  26. visible={this.state.visible}
  27. bodyStyle={{ paddingBottom: 80 }}
  28. footer={
  29. <div
  30. style={{
  31. textAlign: 'right',
  32. }}
  33. >
  34. <Button onClick={this.onClose} style={{ marginRight: 8 }}>
  35. Cancel
  36. </Button>
  37. <Button onClick={this.onClose} type="primary">
  38. Submit
  39. </Button>
  40. </div>
  41. }
  42. >
  43. <Form layout="vertical" hideRequiredMark>
  44. <Row gutter={16}>
  45. <Col span={12}>
  46. <Form.Item
  47. name="name"
  48. label="Name"
  49. rules={[{ required: true, message: 'Please enter user name' }]}
  50. >
  51. <Input placeholder="Please enter user name" />
  52. </Form.Item>
  53. </Col>
  54. <Col span={12}>
  55. <Form.Item
  56. name="url"
  57. label="Url"
  58. rules={[{ required: true, message: 'Please enter url' }]}
  59. >
  60. <Input
  61. style={{ width: '100%' }}
  62. addonBefore="http://"
  63. addonAfter=".com"
  64. placeholder="Please enter url"
  65. />
  66. </Form.Item>
  67. </Col>
  68. </Row>
  69. <Row gutter={16}>
  70. <Col span={12}>
  71. <Form.Item
  72. name="owner"
  73. label="Owner"
  74. rules={[{ required: true, message: 'Please select an owner' }]}
  75. >
  76. <Select placeholder="Please select an owner">
  77. <Option value="xiao">Xiaoxiao Fu</Option>
  78. <Option value="mao">Maomao Zhou</Option>
  79. </Select>
  80. </Form.Item>
  81. </Col>
  82. <Col span={12}>
  83. <Form.Item
  84. name="type"
  85. label="Type"
  86. rules={[{ required: true, message: 'Please choose the type' }]}
  87. >
  88. <Select placeholder="Please choose the type">
  89. <Option value="private">Private</Option>
  90. <Option value="public">Public</Option>
  91. </Select>
  92. </Form.Item>
  93. </Col>
  94. </Row>
  95. <Row gutter={16}>
  96. <Col span={12}>
  97. <Form.Item
  98. name="approver"
  99. label="Approver"
  100. rules={[{ required: true, message: 'Please choose the approver' }]}
  101. >
  102. <Select placeholder="Please choose the approver">
  103. <Option value="jack">Jack Ma</Option>
  104. <Option value="tom">Tom Liu</Option>
  105. </Select>
  106. </Form.Item>
  107. </Col>
  108. <Col span={12}>
  109. <Form.Item
  110. name="dateTime"
  111. label="DateTime"
  112. rules={[{ required: true, message: 'Please choose the dateTime' }]}
  113. >
  114. <DatePicker.RangePicker
  115. style={{ width: '100%' }}
  116. getPopupContainer={trigger => trigger.parentElement}
  117. />
  118. </Form.Item>
  119. </Col>
  120. </Row>
  121. <Row gutter={16}>
  122. <Col span={24}>
  123. <Form.Item
  124. name="description"
  125. label="Description"
  126. rules={[
  127. {
  128. required: true,
  129. message: 'please enter url description',
  130. },
  131. ]}
  132. >
  133. <Input.TextArea rows={4} placeholder="please enter url description" />
  134. </Form.Item>
  135. </Col>
  136. </Row>
  137. </Form>
  138. </Drawer>
  139. </>
  140. );
  141. }
  142. }
  143. ReactDOM.render(<DrawerForm />, mountNode);
  1. .site-form-in-drawer-wrapper {
  2. position: absolute;
  3. right: 0px;
  4. bottom: 0px;
  5. width: 100%;
  6. padding: 10px 16px;
  7. text-align: right;
  8. background: #fff;
  9. border-top: 1px solid #e9e9e9;
  10. }

Drawer抽屉 - 图7

多层抽屉

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

  1. import { Drawer, Button } from 'antd';
  2. class App extends React.Component {
  3. state = { visible: false, childrenDrawer: false };
  4. showDrawer = () => {
  5. this.setState({
  6. visible: true,
  7. });
  8. };
  9. onClose = () => {
  10. this.setState({
  11. visible: false,
  12. });
  13. };
  14. showChildrenDrawer = () => {
  15. this.setState({
  16. childrenDrawer: true,
  17. });
  18. };
  19. onChildrenDrawerClose = () => {
  20. this.setState({
  21. childrenDrawer: false,
  22. });
  23. };
  24. render() {
  25. return (
  26. <>
  27. <Button type="primary" onClick={this.showDrawer}>
  28. Open drawer
  29. </Button>
  30. <Drawer
  31. title="Multi-level drawer"
  32. width={520}
  33. closable={false}
  34. onClose={this.onClose}
  35. visible={this.state.visible}
  36. >
  37. <Button type="primary" onClick={this.showChildrenDrawer}>
  38. Two-level drawer
  39. </Button>
  40. <Drawer
  41. title="Two-level Drawer"
  42. width={320}
  43. closable={false}
  44. onClose={this.onChildrenDrawerClose}
  45. visible={this.state.childrenDrawer}
  46. >
  47. This is two-level drawer
  48. </Drawer>
  49. </Drawer>
  50. </>
  51. );
  52. }
  53. }
  54. ReactDOM.render(<App />, mountNode);

API

参数说明类型默认值版本
afterVisibleChange切换抽屉时动画结束后的回调function(visible)-
bodyStyle可用于设置 Drawer 内容部分的样式CSSProperties-
className对话框外层容器的类名string-
closable是否显示右上角的关闭按钮booleantrue
closeIcon自定义关闭图标ReactNode<CloseOutlined />
contentWrapperStyle可用于设置 Drawer 包裹内容部分的样式CSSProperties-
destroyOnClose关闭时销毁 Drawer 里的子元素booleanfalse
drawerStyle用于设置 Drawer 弹出层的样式CSSProperties-
footer抽屉的页脚ReactNode-
footerStyle抽屉页脚部件的样式CSSProperties-
forceRender预渲染 Drawer 内元素booleanfalse
getContainer指定 Drawer 挂载的 HTML 节点, false 为挂载在当前 domHTMLElement | () => HTMLElement | Selectors | falsebody
headerStyle用于设置 Drawer 头部的样式CSSProperties-
height高度, 在 placementtopbottom 时使用string | number256
keyboard是否支持键盘 esc 关闭booleantrue
mask是否展示遮罩booleantrue
maskClosable点击蒙层是否允许关闭booleantrue
maskStyle遮罩样式CSSProperties{}
placement抽屉的方向top | right | bottom | leftright
push用于设置多层 Drawer 的推动行为boolean | { distance: string | number }{ distance: 180 }4.5.0+
style可用于设置 Drawer 最外层容器的样式,和 drawerStyle 的区别是作用节点包括 maskCSSProperties-
title标题ReactNode-
visibleDrawer 是否可见boolean-
width宽度string | number256
zIndex设置 Drawer 的 z-indexnumber1000
onClose点击遮罩层或右上角叉或取消按钮的回调function(e)-