Ant Design 4.0更新指南(2)——Form

901 阅读3分钟

antd 原有的 Form 组件其实已经足够好用了,但是这次 4.0 对 Form 的更新开始注重不止要好用,还要“优雅”。“优雅”这个东西一直都很玄学。

antd 的 Form 一直以来都很特例独行,区别于其它 antd 组件,Form 的调用并不只是简单的引入组件即可,而是先要进行 Form.create()创建一个 Form 实例,使用 FormItem 时还需在 jsx 中调用 form.getFieldDecorator 方法,写法较为复杂,况且在 jsx 中插入大量的非节点代码,造成代码结构复杂,且一般情况下,一个 Form 表单会有多个 FormItem,也就意味着我们需要重复的去调用 form.getFieldDecorator 方法,导致后期维护成本很高。写这种重复且简单的无意义的代码,这和开篇所说的“优雅”背道而驰。

为了解决这些问题,这次 antd 团队从底层重写了 Form。首先,去掉了 Form.create()这一步操作,改为直接在组件内部去完成。另外将原来的 FormItem 的调用方式也进行了优化,下面是老版本的 FormItem 的调用示例:

<FormItem {...formItemLayout} label="姓名">
  {form.getFieldDecorator("name", {
    rules: [
      {
        required: true,
        message: "姓名不能为空",
      },
    ],
    initialValue: data.name,
  })(<Input placeholder="请输入姓名" />)}
</FormItem>

可以看到,老版本实际上是在组件的 jsx 中调用了 form.getFieldDecorator 方法,本质上是一个高阶组件,然后再将 FormItem 的组件作为参数传入,先不说这种方式复杂与否。如果这个表单有多个 FormItem,这段代码将变得异常混乱。而在 antd 4.0 中,官方也意识到了这个问题,下面是一个新版本 Form 的调用示例:

<Form
  layout="vertical"
  initialValues={{
    name: data.name,
  }}
  onFinish={this.onSubmit}
>
  <Form.Item
    label="姓名"
    name="name"
    rules={[
      {
        required: true,
        message: "姓名不能为空",
      },
    ]}
  >
    <Input placeholder="请输入姓名" />
  </Form.Item>
</Form>

可以看到,FormItem 的调用方式更加纯粹了,更像是一个组件的调用,无需再写冗杂的函数调用代码,这样即使是数据了也能保证代码整洁,降低后期维护成本。表单输入完成后,直接使用 Form 的 onFinish 方法,便可以拿到验证通过之后的数据。弃用了之前的先调用 form.validateFields,然后判断是否验证通过,然后再通过回调拿到验证通过之后的值。又向更加便捷迈进了一步。

同时本次也引入了 ref 句柄,可以通过 ref 来主动调用 validateFields 事件,比如说像这样子:

this.formRef.current
  .validateFields()
  .then((values) => {
    // do somethings
  })
  .catch((errors) => {
    // do somethings
  });

看着这长长的一行代码,你想到了什么?对!就是 jQuery。这种写法真的太像 jQuery 的链式调用啦~让我有一种回到了 DOM 操作的时代,这种方式十分容易理解:先通过 ref 句柄拿到 Form 实例,然后调用它的 validateFields 方法,然后如果校验通过做什么,校验失败又要做什么,十分的语义化,一目了然,代码逻辑一下子就明白了。

最后,官方说了,后期可能会推出跟 ProTable 类似的 ProForm,将基础表单直接封装起来,常用的基础表单直接配置数据即可使用,后期修改也只用维护这份配置数据,做到真正的数据驱动。期待中....

最后说一句,antd 大法好,尽早上车保平安~