Drawer抽屉

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

何时使用

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

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

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

代码演示

Drawer抽屉 - 图1

基础抽屉

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

  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>
  17. <Button type="primary" onClick={this.showDrawer}>
  18. Open
  19. </Button>
  20. <Drawer
  21. title="Basic Drawer"
  22. placement="right"
  23. closable={false}
  24. onClose={this.onClose}
  25. visible={this.state.visible}
  26. >
  27. <p>Some contents...</p>
  28. <p>Some contents...</p>
  29. <p>Some contents...</p>
  30. </Drawer>
  31. </div>
  32. );
  33. }
  34. }
  35. ReactDOM.render(<App />, mountNode);

Drawer抽屉 - 图2

渲染在当前 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. height: 200px;
  3. overflow: hidden;
  4. position: relative;
  5. border: 1px solid #ebedf0;
  6. border-radius: 2px;
  7. padding: 48px;
  8. text-align: center;
  9. background: #fafafa;
  10. }

Drawer抽屉 - 图3

信息预览抽屉

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

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

Drawer抽屉 - 图4

自定义位置

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

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

Drawer抽屉 - 图5

抽屉表单

在抽屉中使用表单。

  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. <div>
  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
  35. onClick={this.onClose}
  36. style={{ marginRight: 8 }}
  37. >
  38. Cancel
  39. </Button>
  40. <Button onClick={this.onClose} type="primary">
  41. Submit
  42. </Button>
  43. </div>
  44. }
  45. >
  46. <Form layout="vertical" hideRequiredMark>
  47. <Row gutter={16}>
  48. <Col span={12}>
  49. <Form.Item
  50. name="name"
  51. label="Name"
  52. rules={[{ required: true, message: 'Please enter user name' }]}
  53. >
  54. <Input placeholder="Please enter user name" />
  55. </Form.Item>
  56. </Col>
  57. <Col span={12}>
  58. <Form.Item
  59. name="url"
  60. label="Url"
  61. rules={[{ required: true, message: 'Please enter url' }]}
  62. >
  63. <Input
  64. style={{ width: '100%' }}
  65. addonBefore="http://"
  66. addonAfter=".com"
  67. placeholder="Please enter url"
  68. />
  69. </Form.Item>
  70. </Col>
  71. </Row>
  72. <Row gutter={16}>
  73. <Col span={12}>
  74. <Form.Item
  75. name="owner"
  76. label="Owner"
  77. rules={[{ required: true, message: 'Please select an owner' }]}
  78. >
  79. <Select placeholder="Please select an owner">
  80. <Option value="xiao">Xiaoxiao Fu</Option>
  81. <Option value="mao">Maomao Zhou</Option>
  82. </Select>
  83. </Form.Item>
  84. </Col>
  85. <Col span={12}>
  86. <Form.Item
  87. name="type"
  88. label="Type"
  89. rules={[{ required: true, message: 'Please choose the type' }]}
  90. >
  91. <Select placeholder="Please choose the type">
  92. <Option value="private">Private</Option>
  93. <Option value="public">Public</Option>
  94. </Select>
  95. </Form.Item>
  96. </Col>
  97. </Row>
  98. <Row gutter={16}>
  99. <Col span={12}>
  100. <Form.Item
  101. name="approver"
  102. label="Approver"
  103. rules={[{ required: true, message: 'Please choose the approver' }]}
  104. >
  105. <Select placeholder="Please choose the approver">
  106. <Option value="jack">Jack Ma</Option>
  107. <Option value="tom">Tom Liu</Option>
  108. </Select>
  109. </Form.Item>
  110. </Col>
  111. <Col span={12}>
  112. <Form.Item
  113. name="dateTime"
  114. label="DateTime"
  115. rules={[{ required: true, message: 'Please choose the dateTime' }]}
  116. >
  117. <DatePicker.RangePicker
  118. style={{ width: '100%' }}
  119. getPopupContainer={trigger => trigger.parentNode}
  120. />
  121. </Form.Item>
  122. </Col>
  123. </Row>
  124. <Row gutter={16}>
  125. <Col span={24}>
  126. <Form.Item
  127. name="description"
  128. label="Description"
  129. rules={[
  130. {
  131. required: true,
  132. message: 'please enter url description',
  133. },
  134. ]}
  135. >
  136. <Input.TextArea rows={4} placeholder="please enter url description" />
  137. </Form.Item>
  138. </Col>
  139. </Row>
  140. </Form>
  141. </Drawer>
  142. </div>
  143. );
  144. }
  145. }
  146. 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. border-top: 1px solid #e9e9e9;
  8. background: #fff;
  9. text-align: right;
  10. }

Drawer抽屉 - 图6

多层抽屉

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

  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. <div>
  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. </div>
  51. );
  52. }
  53. }
  54. ReactDOM.render(<App />, mountNode);

API

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