zoukankan      html  css  js  c++  java
  • 编写antd配置表单组件

    编写antd配置表单组件

    整体思路

    1. 抽取formitem的配置数组:包含组件类型、名称、label名称,相关的opts和扩展的opts,传递进入组件
    2. 组件通过Form.create()进行表单创建,能够带有form属性。并且上层组件引用后能够ref的方式获取form进行操作处理
    3. 基于form能够抽取出来,上层组件能够对下层组件进行调用和操作,在此基础上还能够进行扩展配置和扩展功能的实现
    4. 组件通过props中获取配置数组,动态生成FormItem的表单元素,实现动态配置表单的功能
    5. 组件通过在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}
          />
        );
      }
    }
    
  • 相关阅读:
    How to Enable Trace or Debug for APIs executed as SQL Script Outside of the Applications ?
    Android中MVC、MVP、MVVM具体解释
    破坏性创新第一原则
    Android学习笔记(八)——显示运行进度对话框
    Hadoop知识汇总
    mybatis collection和association使用区别
    mybatis $和#
    IDEA新建一个多maven模块工程(有图)
    可输入的下拉框
    springboot 使用i18n进行国际化
  • 原文地址:https://www.cnblogs.com/fly-piglet/p/10829053.html
Copyright © 2011-2022 走看看