// standardForm.js import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { Form, Input, Row, Col, Button } from 'antd'; const FormItem = Form.Item; // 默认的layout export const defaultLabelColSpan = 8; const defaultFormItemLayout = { labelCol: { span: defaultLabelColSpan }, wrapperCol: { span: 16 }, }; const responsive = { 1: { xs: 24 }, 2: { xs: 24, sm: 12 }, 3: { xs: 24, sm: 12, md: 8 }, 4: { xs: 24, sm: 12, md: 6 }, }; // 监听表单变化 const handleFormChange = (props, changedValues, allValues) => { if (props.onChange) { props.onChange(allValues); } }; class StandardForm extends PureComponent { // 渲染单个表单项 renderFormItem = ({ item, layout, form, columns }) => { const { label, key, required, component, options = {}, rules, extra } = item; const col = columns > 4 ? 4 : columns; return ( <Col {...responsive[col]} key={key}> <FormItem key={key} label={label} {...layout} extra={extra}> {form.getFieldDecorator(key, { normalize: val => (typeof val === 'string' ? val.trim() : val), ...options, form, // 处理复杂的表单校验 rules: rules || [{ required, message: `${label}不能为空` }], })(component || <Input />)} </FormItem> </Col> ); }; onSubmit = e => { e.preventDefault(); const { onSubmit } = this.props; if (onSubmit) { onSubmit(); } }; render() { // items格式即为上文配置的表单项 const { onSubmit, items, layout, columns, form } = this.props; return ( <Form onSubmit={onSubmit && this.onSubmit}> <Row gutter={{ md: 8, lg: 24, xl: 48 }} type="flex" align="top"> {items.map(item => this.renderFormItem({ item, layout, form, columns }))} </Row> <Button type="primary" htmlType="submit" style={{ display: 'none' }}> 搜索 </Button> </Form> ); } } // colums [1,2,3,4] StandardForm.propTypes = { items: PropTypes.array.isRequired, layout: PropTypes.object, columns: PropTypes.number, form: PropTypes.object.isRequired, }; StandardForm.defaultProps = { layout: defaultFormItemLayout, columns: 1, }; export default Form.create({ onValuesChange: handleFormChange })(StandardForm);
<StandardForm ref={formRef => { this.formRef = formRef; }} items={formConfig} layout={{ labelCol: { span: 7 }, wrapperCol: { span: 17 }, }} columns={3} />