編寫antd配置表單組件
阿新 • • 發佈:2019-05-08
items dex pure 返回 輸入 ret ... 自帶 ops
編寫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}
/>
);
}
}
編寫antd配置表單組件