上一篇文章当中,初步介绍了 ProComponents 中的表格、表单和布局,今天就深入讲解一下 ProComponents 中的表单开发。

用 ProComponents 进行开发提效(二)

表单的本质

首先要了解什么是表单?表单的本质就是:

使用合适的表单项组件,将用户的输入收集到一个对象当中。

以常见的登录表单为例,用户需要输入用户名和密码,登录接口想要的数据格式为:

{
  username: 'keliq',
  password: '123456'
}

那么在 ProComponents 中,就可以这么写:

<ProForm onFinish={values => console.log(values)}>
  <ProFormText name="username" label="用户名"/>
  <ProFormText.Password name="password" label="密码"/>
</ProForm>

效果如下:

用 ProComponents 进行开发提效(二)

当填写用户名和密码之后,点击提交,此时打开控制台,就能看到 onFinish 回调函数中收集到的用户信息了:

用 ProComponents 进行开发提效(二)

对,表单就是这么简单!不是吗?

用 ProComponents 进行开发提效(二)

选择合适的表单项

还真不是,实际业务中的表单肯定会比上面的用户名密码要复杂,例如产品提了一个用户信息收集的需求,需要获取用户的姓名、性别、出生日期、身高体重、邮箱电话、兴趣爱好等,接口希望传过去的数据格式如下:

{
  name: 'keliq', // 姓名
  gender: 'Male', // 性别
  birthday: '2000-11-02', // 出生日期
  height: 170, // 身高
  weight: 60, // 体重
  email: 'keliq@example.com', // 邮箱
  phone: '18888888888', // 电话
  hobbies: ['football', 'singing'], // 兴趣爱好
}

那么首先就要根据这个结构来设计表单,按照惯例,先把表单的空架子搭好:

<ProForm onFinish={values => console.log(values)}>
  {/* 选择合适的表单项 */}
</ProForm>

然后针对每个字段,选择一种合适的表单项。在 procomponents 中,表单项有很多种:

用 ProComponents 进行开发提效(二)

对于一名资深的前端开发来说,判断字段用哪个表单组件是一件非常容益的事情,我们可以很快得到下面的结论:

  • 姓名:ProFormText
  • 性别:ProFormRadio.Group
  • 出生日期:ProFormDatePicker
  • 身高体重:ProFormDigit
  • 邮箱电话:ProFormText

于是,收集用户信息的表单分分钟就做出来了:

import { ProForm, ProFormText, ProFormRadio, ProFormDatePicker, ProFormDigit } from '@ant-design/pro-components'
const formLayout = {
  labelCol: { span: 4 },
  wrapperCol: { span: 18 },
}
function ProFormUserInfo() {
  return (
    <ProForm {...formLayout} layout="horizontal" onFinish={async (values) => console.log(values)}>
      <ProFormText name="name" label="姓名" />
      <ProFormRadio.Group
        name="gender"
        label="性别"
        fieldProps={{ style: { textAlign: 'left', minWidth: '100%' } }}
        options={[
          { label: '', value: 'Male' },
          { label: '', value: 'Female' },
          { label: '第三性别', value: 'Third' },
        ]}
      />
      <ProFormDatePicker name="birthday" label="出生日期" fieldProps={{ style: { width: '100%' } }} />
      <ProFormDigit name="height" label="身高" addonAfter={'单位厘米cm)'} />
      <ProFormDigit name="weight" label="体重" addonAfter={'单位公斤kg)'}/>
      <ProFormText name="email" label="邮箱" />
      <ProFormText name="phone" label="电话" />
    </ProForm>
  )
}

效果如下:

用 ProComponents 进行开发提效(二)

静态数组和动态数组

细心的同学肯定发现还缺少一项「兴趣爱好」,这个字段是一个数组,这个应该怎么做呢?有两种场景:

  • 静态数组:只允许添加指定数量的兴趣项
  • 动态数组:用户可以动态添加各种兴趣项

对于第一种场景,可以用 ProFormFieldSet 组件,它可以指定固定数量的表单项:

<ProFormFieldSet name="hobbies" label="兴趣爱好">
  <ProFormText placeholder="请输入兴趣爱好1" />
  <ProFormText placeholder="请输入兴趣爱好2" />
  <ProFormText placeholder="请输入兴趣爱好3" />
</ProFormFieldSet>

效果如下:

用 ProComponents 进行开发提效(二)

而对于第二种场景,就不得不提到强大的 ProFormList 组件了,不仅支持动态删减表单项,还支持嵌套的对象结构,例如下面的效果:

用 ProComponents 进行开发提效(二)

ProFormList 实现的代码是:

<ProFormList name="hobbies" label="兴趣爱好">
  <Flex gap={10}>
    <ProFormText name="name" placeholder="请输入兴趣爱好名称" />
    <ProFormSelect
      name="level"
      options={[
        { value: 'beginner', label: '入门选手' },
        { value: 'ordinary', label: '普通选手' },
        { value: 'profession', label: '专业选手' },
      ]}
      placeholder="请选择专业度"
    />
  </Flex>
</ProFormList>

放在 ProForm 表单中拿到的值是一个对象数组:

用 ProComponents 进行开发提效(二)

处理依赖项

学会了如何在表单中收集数组项之后,我们再来增加一下复杂度:增加婚姻状态选项(未婚、已婚、离异、丧偶),如果用户选择已婚,在下面联动出现一个配偶姓名的表单项。

那这个需求应该怎么做呢?答案是 ProFormDependency组件,为了简化起见,做了只有三个项目的表单:

<ProForm onFinish={async (values) => console.log(values)}>
  <ProFormText name="name" label="姓名" />
  <ProFormSelect
    name="marriage"
    label="婚姻状态"
    options={[
      { value: 0, label: '未婚' },
      { value: 1, label: '已婚' },
      { value: 2, label: '离异' },
      { value: 3, label: '丧偶' },
    ]}
  />
  <ProFormDependency name={['marriage']}>
    {({ marriage }) => {
      return marriage === 1 ? <ProFormText name="spouse" label="配偶姓名" /> : null
    }}
  </ProFormDependency>
</ProForm>

效果如下:

用 ProComponents 进行开发提效(二)

只有当「婚姻状态」字段选择了「已婚」的时候,才展示「配偶姓名」字段。

编辑时回填表单

在很多场景中,用户提交表单之后,还可以继续查看和编辑表单,我们就需要从接口中获取数据,然后回填到表单当中,怎么处理呢?其实非常简单,只需要给 ProForm 添加 initialValues 选项即可,示例代码:

function ProFormEdit() {
  const initialValues = {
    name: 'keliq',
    phone: '18888888888',
    address: '北京天坛公园',
  }
  return (
    <ProForm onFinish={async (values) => console.log(values)} initialValues={initialValues}>
      <ProFormText name="name" label="收件人" />
      <ProFormText name="phone" label="电话" />
      <ProFormText name="address" label="地址" />
    </ProForm>
  )
}

效果如下

用 ProComponents 进行开发提效(二)

学到这里,使用 ProComponents 来开发表单的基础知识都已经讲完了,能够覆盖大部分的业务场景,赶快在自己的项目中练习一下吧!