// 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}
/>