antd3.x Drawer文档 https://3x.ant.design/components/drawer-cn

DrawerForm

image.png

DrawerForm.js

  1. import React, { useState } from 'react';
  2. import PropTypes from 'prop-types';
  3. import {
  4. Drawer, Form, Button, Col, Row, Input, Select, DatePicker
  5. } from 'antd';
  6. const { Item } = Form;
  7. const { Option } = Select;
  8. DrawerpropTypes = {
  9. title: PropTypes.string,
  10. value: PropTypes.object,
  11. onChange: PropTypes.func.isRequired,
  12. };
  13. DrawerdefualtProps = {
  14. title: '新增账户',
  15. value: {},
  16. };
  17. function DrawerForm({ title, value, onChange, form }) {
  18. const [visible, setVisible] = useState(false);
  19. const { getFieldDecorator } = form;
  20. const onShow = () => setVisible(true);
  21. const onClose = () => {
  22. setVisible(false);
  23. form.resetFields();
  24. };
  25. function onSubmit() {
  26. form.validateFieldsAndScroll((err, values) => {
  27. if (err) return
  28. onChange(values)
  29. onClose()
  30. })
  31. }
  32. const attr = {
  33. title,
  34. visible,
  35. width: 720,
  36. closable: false,
  37. onClose,
  38. }
  39. return (
  40. <>
  41. <Button onClick={onShow}>新建</Button>
  42. <Drawer {...attr}>
  43. <Form onSubmit={onSubmit}>
  44. <Row gutter={16}>
  45. <Col span={12}>
  46. <Item label="用户名">
  47. {getFieldDecorator('name', {
  48. rules: [{ required: true, message: 'Please' }],
  49. initialValue: value.name,
  50. })(<Input placeholder="Please" />)}
  51. </Item>
  52. </Col>
  53. <Col span={12}>
  54. <Item label="网站">
  55. {getFieldDecorator('url', {
  56. rules: [{ required: true, message: 'Please' }],
  57. initialValue: value.url,
  58. })(
  59. <Input
  60. className='full'
  61. addonBefore="http://"
  62. addonAfter=".com"
  63. placeholder="Please"
  64. />,
  65. )}
  66. </Item>
  67. </Col>
  68. <Col span={12}>
  69. <Item label="建议">
  70. {getFieldDecorator('approver', {
  71. rules: [{ required: true, message: 'Please choose the approver' }],
  72. initialValue: value.approver,
  73. })(
  74. <Select placeholder="Please choose the approver">
  75. <Option value="jack">Jack Ma</Option>
  76. <Option value="tom">Tom Liu</Option>
  77. </Select>,
  78. )}
  79. </Item>
  80. </Col>
  81. <Col span={12}>
  82. <Item label="日期">
  83. {getFieldDecorator('time', {
  84. rules: [{ required: true, message: 'Please choose the dateTime' }],
  85. initialValue: value.time,
  86. })(
  87. <DatePicker.RangePicker
  88. className='full'
  89. getPopupContainer={trigger => trigger.parentNode}
  90. />,
  91. )}
  92. </Item>
  93. </Col>
  94. <Col span={24}>
  95. <Item label="描述">
  96. {getFieldDecorator('description', {
  97. rules: [
  98. { required: true, message: 'please' },
  99. ],
  100. initialValue: value.description,
  101. })(<Input.TextArea rows={4} placeholder="please" />)}
  102. </Item>
  103. </Col>
  104. </Row>
  105. </Form>
  106. <div className="drawer-action">
  107. <Button onClick={onClose} className="mr16" block>
  108. 取消
  109. </Button>
  110. <Button htmlType='submit' type="primary" block>
  111. 确定
  112. </Button>
  113. </div>
  114. </Drawer>
  115. </>
  116. )
  117. }
  118. export default Form.create()(DrawerForm);

DrawerCard

image.png

DrawerCard.js

  1. import React, { useState } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { Card, Drawer, Button, Icon, Row, Col } from 'antd';
  4. const options = [
  5. { label: '股票', value: 1, icon: 'stock' },
  6. { label: '债券', value: 2, icon: 'bar-chart' },
  7. { label: '期货', value: 3, icon: 'ordered-list' },
  8. { label: '大宗商品', value: 4, icon: 'control' },
  9. { label: '固定收益', value: 5, icon: 'sliders' },
  10. ];
  11. DrawerCard.propTypes = {
  12. title: PropTypes.string,
  13. onChange: PropTypes.func.isRequired,
  14. };
  15. DrawerCard.defualtProps = {
  16. title: '请选择理财产品',
  17. };
  18. function DrawerCard({ title, onChange }) {
  19. const [visible, setVisible] = useState(false);
  20. const [selected, setSelected] = useState(1);
  21. const onShow = () => setVisible(true);
  22. const onClose = () => setVisible(false);
  23. const onClick = value => setSelected(value);
  24. const onSubmit = () => {
  25. onChange(selected);
  26. onClose();
  27. };
  28. const attr = {
  29. width: 400,
  30. title,
  31. visible,
  32. onClose,
  33. closable: false, // 不显示标题右侧的X
  34. maskClosable: false, // 点击遮罩不关闭抽递
  35. };
  36. return (
  37. <>
  38. <Button onClick={onShow}>新建</Button>
  39. <Drawer {...attr}>
  40. <Row gutter={16}>
  41. {options.map(({ label, value, icon }) => {
  42. return (
  43. <Col key={value} span={12} className="mb16 text-center">
  44. <Card
  45. hoverable
  46. size="small"
  47. className={selected === value ? 'card-selected' : ''}
  48. onClick={() => onClick(value)}
  49. >
  50. <Icon type={icon} className='fontSize32 mb16' />
  51. <footer>{label}</footer>
  52. </Card>
  53. </Col>
  54. );
  55. })}
  56. </Row>
  57. <div className="drawer-action">
  58. <Button onClick={onClose} className="mr16" block>
  59. 取消
  60. </Button>
  61. <Button onClick={onSubmit} type="primary" block>
  62. 确定
  63. </Button>
  64. </div>
  65. </Drawer>
  66. </>
  67. );
  68. }
  69. export default DrawerCard;

index.less

放到 src/index.less里面作为一个全局的样式

  1. // Drawer 确定取消样式
  2. .drawer-action {
  3. display: flex;
  4. position: absolute;
  5. right: 0;
  6. bottom: 0;
  7. width: 100%;
  8. padding: 8px 16px;
  9. background-color: #fff;
  10. border-top: 1px solid #dedede;
  11. text-align: right;
  12. }
  13. // Card 选中样式
  14. .card-selected {
  15. background-color: #0070cc;
  16. border-color: #0070cc;
  17. color: #fff;
  18. }