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
  17. style={{
  18. height: 200,
  19. overflow: 'hidden',
  20. position: 'relative',
  21. border: '1px solid #ebedf0',
  22. borderRadius: 2,
  23. padding: 48,
  24. textAlign: 'center',
  25. background: '#fafafa',
  26. }}
  27. >
  28. Render in this
  29. <div style={{ marginTop: 16 }}>
  30. <Button type="primary" onClick={this.showDrawer}>
  31. Open
  32. </Button>
  33. </div>
  34. <Drawer
  35. title="Basic Drawer"
  36. placement="right"
  37. closable={false}
  38. onClose={this.onClose}
  39. visible={this.state.visible}
  40. getContainer={false}
  41. style={{ position: 'absolute' }}
  42. >
  43. <p>Some contents...</p>
  44. </Drawer>
  45. </div>
  46. );
  47. }
  48. }
  49. ReactDOM.render(<App />, mountNode);

Drawer抽屉 - 图3

信息预览抽屉

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

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

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

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. <div
  50. style={{
  51. position: 'absolute',
  52. bottom: 0,
  53. width: '100%',
  54. borderTop: '1px solid #e8e8e8',
  55. padding: '10px 16px',
  56. textAlign: 'right',
  57. left: 0,
  58. background: '#fff',
  59. borderRadius: '0 0 4px 4px',
  60. }}
  61. >
  62. <Button
  63. style={{
  64. marginRight: 8,
  65. }}
  66. onClick={this.onClose}
  67. >
  68. Cancel
  69. </Button>
  70. <Button onClick={this.onClose} type="primary">
  71. Submit
  72. </Button>
  73. </div>
  74. </Drawer>
  75. </div>
  76. );
  77. }
  78. }
  79. ReactDOM.render(<App />, mountNode);

API

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