自定义表单

共有属性

{
  label: 'label',
  name: 'name',
  type: "Switch",

  disabled: true,
  show: true,
  defaultValue: 1
}
1
2
3
4
5
6
7
8
9

Input

const fields = [
  {
    name: "Input",
    label: "Input",
    type: "Input",
    placeholder: "请选择",
    addonAfter: (
      <Icon
        type="search"
        onClick={() => {
          this.handleSelectOrg();
        }}
      />
    )
  }
];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Switch

const fields = [
  {
    name: "singinFlg",
    label: "是否签到",
    type: "Switch",
    checkedChildren: "是",
    unCheckedChildren: "否"
  }
];
1
2
3
4
5
6
7
8
9

Radio

const fields = [
  {
    name: "Radio",
    label: "Radio",
    type: "Radio",
    options: [{ label: "Radio", value: 1 }]
  }
];
1
2
3
4
5
6
7
8

如果 label 和 value 是相同的则可以为字符串数组

const fields = [
  {
    name: "Radio",
    label: "Radio",
    type: "Radio",
    options: ["Apple", "Banana"]
  }
];
1
2
3
4
5
6
7
8

RangePicker

const fields = [
  {
    name: "RangePicker",
    label: "RangePicker",
    type: "RangePicker"
  }
];
1
2
3
4
5
6
7

Custom

const fields = [
  {
    name: "Custom",
    type: "Custom",
    label: "Custom",
    node: <div>Plain</div>
  }
];
1
2
3
4
5
6
7
8
const fields = [
  {
    name: "custom",
    type: "custom",
    label: "Plain Text",
    node: <div>Plain</div>
  },
  {
    name: "name",
    label: "名称",
    type: "input",
    placeholder: "请输入名称",
    rules: [
      {
        required: true,
        message: "请输入名称"
      }
    ]
  },
  {
    name: "size",
    label: "大小",
    type: "inputNumber",
    placeholder: "请输入大小",
    rules: [
      {
        required: true,
        message: "请输入名称"
      }
    ]
  },
  {
    name: "city",
    label: "城市",
    type: "select",
    options: [
      {
        label: "北京",
        value: 0
      }
    ]
  },
  {
    name: "fruit",
    label: "水果",
    mode: "multiple",
    type: "select",
    options: [
      {
        label: "苹果",
        value: "applue"
      },
      {
        label: "香蕉",
        value: "banana"
      }
    ]
  },
  {
    name: "slider",
    type: "slider",
    label: "Slider",
    marks: {
      0: "A",
      20: "B",
      40: "C",
      60: "D",
      80: "E",
      100: "F"
    }
  },
  {
    name: "area",
    label: "地区",
    type: "radio",
    options: ["城区", "郊区"]
  },
  {
    name: "confirm",
    label: "确认选择",
    type: "checkbox"
  },
  {
    name: "checkboxGroup",
    label: "确认选择",
    type: "checkboxGroup",
    options: ["是", "否"],
    onChange: e => console.log("e", e),
    rules: [
      {
        required: true,
        message: "请确认选择"
      }
    ]
  },
  {
    name: "custom",
    label: "自定义项",
    type: "custom",
    node: (
      <div>
        <h2>自定义表单项</h2>
      </div>
    )
  },
  {
    name: "password",
    label: "密码",
    type: "password",
    rules: [
      {
        required: true,
        message: "请输入密码"
      }
    ]
  },
  {
    name: "choosen",
    label: "是否选择",
    type: "switch",
    checkedChildren: "开",
    unCheckedChildren: "关",
    rules: [
      {
        required: true,
        message: "请输入密码"
      }
    ]
  },
  {
    name: "rate",
    label: "评分",
    type: "rate"
  },
  {
    name: "describe",
    label: "描述",
    type: "textarea",
    placeholder: "请输入描述"
  }
];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

完全受控表单

const mapPropsToFields = props => {
  const { data, fields } = props;
  const nameList = fields.map(field => field.name);
  const fieldProps = nameList.reduce((result, name) => {
    const value = data[name];
    if (value) {
      const curData = {
        [name]: Form.createFormField({
          // ...props.username,
          value
        })
      };
      return { ...result, ...curData };
    }
    return result;
  }, {});
  return fieldProps;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

非受控组件

import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import { Form } from "antd";

import XField from "../XField";

const formItemLayout = {
  labelCol: {
    xs: { span: 24 },
    sm: { span: 8 },
    xl: { span: 4 }
  },
  wrapperCol: {
    xs: { span: 24 },
    sm: { span: 16 },
    xl: { span: 20 }
  }
};

@Form.create()
export default class index extends PureComponent {
  static propTypes = {
    fields: PropTypes.array,
    onSearch: PropTypes.func,
    onReset: PropTypes.func,
    onChange: PropTypes.func
  };

  static defaultProps = {
    data: {},
    fields: [],
    formItemLayout,
    onSubmit() {}
  };

  getValuePropName(type) {
    switch (type) {
      case "switch":
      case "checkbox":
        return "checked";
      default:
        return "value";
    }
  }

  getFieldDecoratorOptions = (fieldProps, data) => {
    const { rules, type, name, fieldDecoratorOptions = {} } = fieldProps;

    const valuePropName = this.getValuePropName(type);
    const value = data[name];
    const initialValue = valuePropName === "checked" ? Boolean(value) : value;

    const options = {
      initialValue,
      valuePropName,
      rules: rules,
      ...fieldDecoratorOptions
    };
    return options;
  };

  render() {
    const {
      fields,
      data,
      children,
      formItemLayout,
      form: { getFieldDecorator },
      ...restProps
    } = this.props;

    return (
      <Form {...formItemLayout} {...restProps}>
        {fields.map(field => {
          const { label, name } = field;
          const options = this.getFieldDecoratorOptions(field, data);
          return (
            <Form.Item key={name} label={label}>
              {getFieldDecorator(name, options)(<XField {...field} />)}
            </Form.Item>
          );
        })}
        {children}
      </Form>
    );
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
上次更新: 11/6/2019, 11:36:02 AM