编写antd配置表单组件
整体思路
- 抽取formitem的配置数组:包含组件类型、名称、label名称,相关的opts和扩展的opts,传递进入组件
- 组件通过Form.create()进行表单创建,能够带有form属性。并且上层组件引用后能够ref的方式获取form进行操作处理
- 基于form能够抽取出来,上层组件能够对下层组件进行调用和操作,在此基础上还能够进行扩展配置和扩展功能的实现
- 组件通过props中获取配置数组,动态生成FormItem的表单元素,实现动态配置表单的功能
- 组件通过在create中的mapPropsToFields中将外部对象数据data绑定到内部表单Item中了
实例实现代码,基于react和antd,类似的组件实现思路一致
组件js
import React, { PureComponent } from 'react';
import { Row, Form, Input, Col } from 'antd';
import FormItem from 'antd/lib/form/FormItem';
import BaseDataForm from '.';
// 通用组件
class _BaseDataForm extends PureComponent {
// 默认属性
defaultProps = {
fields: [], // 外部传递进来的配置数据
}
state = {
}
getFromItems = () => {
const { form } = this.props;
const { getFieldDecorator } = form;
const { fields, labelCol, wrapperCol } = this.props;
const children = [];// 定义返回值数组
const fieldsinput = fields || [];
const labelColinput = labelCol || 7;
const wrapperColinput = wrapperCol || 15;
const formItemLayout = {
labelCol: { span: labelColinput },
wrapperCol: { span: wrapperColinput },
};
for (let index = 0; index < fieldsinput.length; index += 1) {
const field = fieldsinput[index];
let item = '';
if (field.type === 'Input' || field.type === 'password') {
// this.props.form.getFieldDecorator(id, options) 使用功能这个包装空间,id等于属性名
item = getFieldDecorator(field.name, field.fieldDecoratorOps)(
<Input {...field.elementOpts} />
);
}
// 拼装表格
children.push(
<Col key={index}>
<FormItem {...formItemLayout} label={field.label}>
{item}
</FormItem>
</Col>
);
}
return children;
}
render() {
return (
<Form>
<Row>{this.getFields()}</Row>
</Form>
);
}
}
导入js
// 经过Form.create包装过的组件会自带this.props.form
const BaseDataForm = Form.create({
mapPropsToFields: (props) => {
// 把父组件的属性映射到表单项上(如:把 Redux store 中的值读出),需要对返回值中的表单域数据用 Form.createFormField 标记,注意表单项将变成受控组件, error 等也需要一并手动传入
const { fields = [], data = [] } = props;
const values = {};
fields.map(item => {
const fieldName = item.name;
let value = data[fieldName];
if (fieldName.indexOf('.' !== -1)) {
try {
// eslint-disable-next-line no-eval
value = eval('data.' + fieldName);
// 特殊多层结构数据获取值
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
}
if (value !== undefined && value !== null) {
// 特殊数据处理
}
values[fieldName] = Form.createFormField({ value });
return item;
});
return values;
},
})(_BaseDataForm);
export default BaseDataForm;
实例js
class Test extends PureComponent {
exampleFields = [
{
type: 'Input',
name: 'test',
label: '输入1',
fieldDecoratorOps: {}, // 表单绑定属性
elementOpts: {}, // 标签属性
},
{
type: 'Input',
name: 'test2',
label: '输入2',
fieldDecoratorOps: {}, // 表单绑定属性
elementOpts: {}, // 标签属性
},
];
saveFormRef = (form) => {
this.form = from;
}
getFormData = () => {
return this.form.getFieldsValue();
}
render() {
return (
<BaseDataForm
ref={this.saveFormRef} // 通过ref将对应的表单from组件映射出来,能够直接调用
data={{}} // data在创建表单的时候做了一次绑定,这个绑定能够将当前值显示进去
fields={exampleFields}
/>
);
}
}