Form 表单在数栈的应用(下):深入篇
这篇文章的主题为我们对 Form 表单在数栈产品中使用之后理解消化的一个过程,通过介绍一些 Form 表单中常用到的方法,来理解部分设计思想,加深我们对技术的追求。主要介绍 Form 表单的创建和 Form表单双向绑定(getFieldDecorator)。
后文中所提到的 Form 表单均为 Antd 3.x 中的 Form 组件,以下简称为 Form 表单。在 Form 表单在数栈的应用(上): 校验篇 中提到,我们生在一个最好的时代,其实是别人造好轮子帮我们做了一些事情,那我们今天看一看,别人的轮子是怎么造的,我们自己能不能实现。 留心过 Antd 的同学可能有印象,Antd 是基于 react-component 组件进行了 UI 封装,文章会以 react-component/form 的代码为主。
一、别人的 Form
1.1 From.create
先查看 createForm.js 文件,该文件主要是对 createBaseForm.js
文件进行了一层封装,并加上一些常用的方法。
接下来查看一下 createBaseForm.js 文件,主要查看该文件中的 createBaseForm
方法,这个方法起到装饰器的作用,在 props 中包装了一个默认为 form 的变量,在这个变量中完成 Form 的所有功能。createBaseForm
的作用是拷贝当前传递来的组件,也就是调用函数将当前组件传递下去作为被包装组件,最终返回一个被包装过的具备新属性的组件。
装饰器(decorator): 是一种与
类
相关的语法,主要用来修改类和类方法(类属性),大部分面向对象的编程语言都支持这种语法,比如Java、Python。装饰器可以简单理解为:能对一些对象
进行修改,然后返回一个被包装过的对象
。
综合来看,Form.create(options)
实际上是对我们的业务组件进行了一次封装,进行了 Form 相关属性的初始化,挂载了一些需要使用的方法,并将这些方法添加到 props.form 下。
1.2 getFieldDecorator
从上述使用代码和下方实现方法可以看出,getFieldDecorator
是一个柯里化的函数,通过 id 和参数的输入,返回以输入组件为入参加上新属性的一个 Dom 节点,把 option 的valuePropName、getValueProps、initialValue、rules 等各种 props 挂载到输入组件上。
getFieldDecorator
有以下两个作用,可在 createBaseForm.js
文件的 getFieldProps
和 getFieldValuePropValue
方法中分别验证:
- 在初始化数据字段时将数据字段放到
fieldsStore
中; - 挂载 props 到输入组件上时会从
fieldsStore
中读取数据字段。
1.3 validateFields
通常使用 validateFields
方法对我们的表单数据进行校验,查看 createBaseForm.js
文件中 validateFields
方法的实现后,发现 validateFields
方法返回一个 Promise 并且拼装 validateFieldsInternal
方法需要的参数。
再看 validateFieldsInternal
方法的代码,它会从 fieldsStore
中获取 rules 和数据 fields 的值,校验后将错误信息分别存储到对应的 fieldsStore
中。
总得来说,Form 表单从初始化到表单收集校验经过了以下几个步骤: 1、通过 Form.create
方法初始了一些属性到 props.form
中,供开发者调用; 2、通过 getFieldDecorator
初始化表单的属性和值,达到双向绑定的效果; 3、校验通过,把数据存到 fieldsStore
中;校验不通过,把 error 存到 fieldsStore
中,渲染。
二、自己的 Form
效果和代码可以在 https://stackblitz.com/edit/react-ts-uoj5pj 查看。
2.1 getFieldDecorator
2.2 validateFields
2.3 createForm