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

抽屉表单

在抽屉中使用表单。

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

Drawer抽屉 - 图3

多层抽屉

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

  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);

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, 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 key={item.id} actions={[<a onClick={this.showDrawer}>View Profile</a>]}>
  57. <List.Item.Meta
  58. avatar={
  59. <Avatar src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png" />
  60. }
  61. title={<a href="https://ant.design/index-cn">{item.name}</a>}
  62. description="Progresser AFX"
  63. />
  64. </List.Item>
  65. )}
  66. />
  67. <Drawer
  68. width={640}
  69. placement="right"
  70. closable={false}
  71. onClose={this.onClose}
  72. visible={this.state.visible}
  73. >
  74. <p style={{ ...pStyle, marginBottom: 24 }}>User Profile</p>
  75. <p style={pStyle}>Personal</p>
  76. <Row>
  77. <Col span={12}>
  78. <DescriptionItem title="Full Name" content="Lily" />{' '}
  79. </Col>
  80. <Col span={12}>
  81. <DescriptionItem title="Account" content="AntDesign@example.com" />
  82. </Col>
  83. </Row>
  84. <Row>
  85. <Col span={12}>
  86. <DescriptionItem title="City" content="HangZhou" />
  87. </Col>
  88. <Col span={12}>
  89. <DescriptionItem title="Country" content="China🇨🇳" />
  90. </Col>
  91. </Row>
  92. <Row>
  93. <Col span={12}>
  94. <DescriptionItem title="Birthday" content="February 2,1900" />
  95. </Col>
  96. <Col span={12}>
  97. <DescriptionItem title="Website" content="-" />
  98. </Col>
  99. </Row>
  100. <Row>
  101. <Col span={24}>
  102. <DescriptionItem
  103. title="Message"
  104. content="Make things as simple as possible but no simpler."
  105. />
  106. </Col>
  107. </Row>
  108. <Divider />
  109. <p style={pStyle}>Company</p>
  110. <Row>
  111. <Col span={12}>
  112. <DescriptionItem title="Position" content="Programmer" />
  113. </Col>
  114. <Col span={12}>
  115. <DescriptionItem title="Responsibilities" content="Coding" />
  116. </Col>
  117. </Row>
  118. <Row>
  119. <Col span={12}>
  120. <DescriptionItem title="Department" content="AFX" />
  121. </Col>
  122. <Col span={12}>
  123. <DescriptionItem title="Supervisor" content={<a>Lin</a>} />
  124. </Col>
  125. </Row>
  126. <Row>
  127. <Col span={24}>
  128. <DescriptionItem
  129. title="Skills"
  130. 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."
  131. />
  132. </Col>
  133. </Row>
  134. <Divider />
  135. <p style={pStyle}>Contacts</p>
  136. <Row>
  137. <Col span={12}>
  138. <DescriptionItem title="Email" content="AntDesign@example.com" />
  139. </Col>
  140. <Col span={12}>
  141. <DescriptionItem title="Phone Number" content="+86 181 0000 0000" />
  142. </Col>
  143. </Row>
  144. <Row>
  145. <Col span={24}>
  146. <DescriptionItem
  147. title="Github"
  148. content={
  149. <a href="http://github.com/ant-design/ant-design/">
  150. github.com/ant-design/ant-design/
  151. </a>
  152. }
  153. />
  154. </Col>
  155. </Row>
  156. </Drawer>
  157. </div>
  158. );
  159. }
  160. }
  161. ReactDOM.render(<App />, mountNode);

API

参数说明类型默认值
closable是否显示右上角的关闭按钮booleantrue
destroyOnClose关闭时销毁 Drawer 里的子元素booleanfalse
getContainer指定 Drawer 挂载的 HTML 节点HTMLElement | () => HTMLElement | Selectors'body'
maskClosable点击蒙层是否允许关闭booleantrue
mask是否展示遮罩Booleantrue
maskStyle遮罩样式object{}
style可用于设置 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' | 'left''right'
onClose点击遮罩层或右上角叉或取消按钮的回调function(e)
afterVisibleChange切换抽屉时动画结束后的回调function(visible)
keyboard是否支持键盘 esc 关闭booleantrue