基于antd 3.x 的自定义表单实现方案

问题

  1. 表单逻辑复杂需要大量自定义表单满足需求
  2. 表单字段过多嵌套过深
  3. 表单校验问题

解决办法:通过组合自定义表单组件实现复杂的表单的逻辑和校验功能

父级表单

  • childFormItem
  • getInstance
@Form.create()
@withRef
class Parent extends Component {
    constructor(props) {
        super(props);
        this.childFormItem = null;
        this.state = {
            formValues: {}
        };
    }
    
    componentWillUnMount(){
     this.childFormItem = null;
    }

    render() {
        const { formValues } = this.state
        const { getFieldDecorator} = form;
        return (
            <div >
                <FormItem>
                    {
                        getFieldDecorator(`formValue`, {
                            initialValue: formValues,
                            rules: [
                                {
                                    required: true,
                                    message: "请输入前提条件"
                                }
                            ]
                        })(
                            <ChildFirmItem
                                getInstance={ins => this.childFormItem = ins}
                                onChange={this.handleChange.bind(this)}
                            />
                        )
                    }
                </FormItem>
            </div>
        );
    }

    // 校验
    handleVerifyValue() {
        // 校验并拼接返回值
        return new Promise((resolve, reject) => {
            this.props.form.validateFields(async (error, values) => {
                if (error) return reject(error);
                const [err, values] = await to(this.childFormItem.handleVerifyValue());
                if (err) return reject(err);
                return resolve(values)
            })
         })
    }


    // 更新value
    handleChange() {
        setTimeout(() => {
            const value = this.props.form.getFieldsValue();
            this.props.onChange(formValues);
        });
    }
}

自定义子组件

  • @withRef
  • handleChange
  • handleVerifyValue
@Form.create()
@withRef
class Child extends Component {
  constructor(props) {
    super(props);
  }

  // 校验
  handleVerifyValue() {
    return new Promise((resolve, reject) => {
      this.props.form.validateFields((error, values) => {
        if (error) {
          return reject(error)
        } else {
          return resolve(values)
        }
      })
    })
  }
  
  //更新value
  handleChange () {  
    setTimeout(() => {
      const values = this.props.form.getFieldsValue();
      this.props.onChange(values);
    });
  }

  render() {
    const { form, value  } = this.props
    const { getFieldDecorator } = form
    return (
     <FormItem>
        {
          getFieldDecorator("dtFormat", {
            initialValue: value.dtFormat || void 0",
            rules: [
              {
                required: true,   
                message: "请输入"
              }
            ]
          })(
            <Input
              type="text"
              placeholder={"请输入"}
              onChange={this.handleChange.bind(this)}
            />
          )
        }
      </FormItem>   
    )
  }
}

@withRef

export default (WrappedComponent) => {
  return class withRef extends Component {
    static displayName = `withRef(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
    render() {
      const props = { ...this.props };
      // 在这里把getInstance赋值给ref,
      props.ref = (el) => {
        this.props.getInstance && this.props.getInstance(el);
        this.props.ref && this.props.ref(el);
      }

      return (
        <WrappedComponent {...props} />
      );
    }
  };
};
原文地址:https://www.cnblogs.com/chrissong/p/12633977.html