image.png
参考资料 antd-from https://3x.ant.design/components/form-cn
formily https://github.com/alibaba/formily/blob/master/README.zh-cn.md
formily schema https://zhuanlan.zhihu.com/uform

form的用法

  1. import { Form, Row, Col, Input, Button, Icon } from 'antd';
  2. class AdvancedSearchForm extends React.Component {
  3. state = {
  4. expand: false,
  5. };
  6. // To generate mock Form.Item
  7. getFields() {
  8. const count = this.state.expand ? 10 : 6;
  9. const { getFieldDecorator } = this.props.form;
  10. const children = [];
  11. for (let i = 0; i < 10; i++) {
  12. children.push(
  13. <Col span={8} key={i} style={{ display: i < count ? 'block' : 'none' }}>
  14. <Form.Item label={`Field ${i}`}>
  15. {getFieldDecorator(`field-${i}`, {
  16. rules: [
  17. {
  18. required: true,
  19. message: 'Input something!',
  20. },
  21. ],
  22. })(<Input placeholder="placeholder" />)}
  23. </Form.Item>
  24. </Col>,
  25. );
  26. }
  27. return children;
  28. }
  29. handleSearch = e => {
  30. e.preventDefault();
  31. this.props.form.validateFields((err, values) => {
  32. console.log('Received values of form: ', values);
  33. });
  34. };
  35. handleReset = () => {
  36. this.props.form.resetFields();
  37. };
  38. toggle = () => {
  39. const { expand } = this.state;
  40. this.setState({ expand: !expand });
  41. };
  42. render() {
  43. return (
  44. <Form className="ant-advanced-search-form" onSubmit={this.handleSearch}>
  45. <Row gutter={24}>{this.getFields()}</Row>
  46. <Row>
  47. <Col span={24} style={{ textAlign: 'right' }}>
  48. <Button type="primary" htmlType="submit">
  49. Search
  50. </Button>
  51. <Button style={{ marginLeft: 8 }} onClick={this.handleReset}>
  52. Clear
  53. </Button>
  54. <a style={{ marginLeft: 8, fontSize: 12 }} onClick={this.toggle}>
  55. Collapse <Icon type={this.state.expand ? 'up' : 'down'} />
  56. </a>
  57. </Col>
  58. </Row>
  59. </Form>
  60. );
  61. }
  62. }
  63. const WrappedAdvancedSearchForm = Form.create({ name: 'advanced_search' })(AdvancedSearchForm);
  64. ReactDOM.render(
  65. <div>
  66. <WrappedAdvancedSearchForm />
  67. <div className="search-result-list">Search Result List</div>
  68. </div>,
  69. mountNode,
  70. );

form.css

  1. .ant-advanced-search-form {
  2. padding: 24px;
  3. background: #fbfbfb;
  4. border: 1px solid #d9d9d9;
  5. border-radius: 6px;
  6. }
  7. .ant-advanced-search-form .ant-form-item {
  8. display: flex;
  9. }
  10. .ant-advanced-search-form .ant-form-item-control-wrapper {
  11. flex: 1;
  12. }

FormItem

  1. 面向数据编程,根据数据渲染form表单
  2. 描述表单结构的schema语言,快速生成表单
  1. import React, { isValidElement } from 'react';
  2. const COMPONENT = {};
  3. function FormConfig({ component, valuePropName, ...props }) {
  4. // 传入的是 React组件 <Select />
  5. if (typeof component === 'object' && isValidElement(component)) {
  6. return component;
  7. }
  8. const Component = typeof component === 'function' ? component : COMPONENT[component];
  9. if (!Component) return null;
  10. return <Component {...props} />;
  11. }
  12. export default FormConfig;

dataSource数据格式

数组对象格式

  1. export const jobArray = [
  2. { label: 'UI设计', value: '1' },
  3. { label: '前端开发', value: '2' },
  4. { label: '后端开发', value: '3' },
  5. ]
  6. export default [
  7. {
  8. component: 'Input',
  9. name: 'username',
  10. label: '用户名',
  11. initialValue: '',
  12. placeholder: '请输入用户名',
  13. rules: [
  14. {
  15. required: true,
  16. message: '请输入用户名',
  17. },
  18. ],
  19. onChange: ev => onChange({ key: 'username', value: ev.target.value }),
  20. },
  21. {
  22. component: 'Password',
  23. name: 'password',
  24. label: '密码',
  25. initialValue: '',
  26. placeholder: '请输入密码',
  27. rules: [
  28. {
  29. required: true,
  30. message: '请输入密码',
  31. },
  32. ],
  33. onChange: ev => onChange({ key: 'password', value: ev.target.value }),
  34. },
  35. {
  36. component: 'Select',
  37. name: 'job',
  38. label: '工作',
  39. initialValue: '',
  40. placeholder: '请选择工作',
  41. children: {
  42. component: 'Option',
  43. data: jobArray,
  44. },
  45. rules: [
  46. {
  47. required: true,
  48. message: '请选择工作',
  49. },
  50. ],
  51. onChange: value => onChange({ key: 'job', value }),
  52. },
  53. {
  54. component: 'AutoComplete',
  55. name: 'skill',
  56. label: '技能',
  57. placeholder: '请输入技能',
  58. initialValue: '',
  59. dataSource: [],
  60. filterOption: (input, option) => {
  61. const text = option.props.children.toUpperCase()
  62. return text.indexOf(input) >= 0
  63. },
  64. rules: [
  65. {
  66. required: true,
  67. message: '请输入技能'
  68. },
  69. ],
  70. onChange: value => onChange({ key: 'skill', value }),
  71. },
  72. {
  73. component: 'Switch',
  74. name: 'mg',
  75. label: '特效专业',
  76. initialValue: true,
  77. valuePropName: 'checked',
  78. checkedChildren: '是',
  79. unCheckedChildren: '否',
  80. onChange: value => onChange({ key: 'effective', value }),
  81. },
  82. ]