在上一篇文章当中,初步介绍了 ProComponents 中的表格、表单和布局,今天就深入讲解一下 ProComponents 中的表单开发。
表单的本质
首先要了解什么是表单?表单的本质就是:
使用合适的表单项组件,将用户的输入收集到一个对象当中。
以常见的登录表单为例,用户需要输入用户名和密码,登录接口想要的数据格式为:
js
{
username: 'keliq',
password: '123456'
}
那么在 ProComponents 中,就可以这么写:
jsx
<ProForm onFinish={values => console.log(values)}>
<ProFormText name="username" label="用户名"/>
<ProFormText.Password name="password" label="密码"/>
</ProForm>
效果如下:
当填写用户名和密码之后,点击提交,此时打开控制台,就能看到 onFinish 回调函数中收集到的用户信息了:
对,表单就是这么简单!不是吗?
选择合适的表单项
还真不是,实际业务中的表单肯定会比上面的用户名密码要复杂,例如产品提了一个用户信息收集的需求,需要获取用户的姓名、性别、出生日期、身高体重、邮箱电话、兴趣爱好等,接口希望传过去的数据格式如下:
js
{
name: 'keliq', // 姓名
gender: 'Male', // 性别
birthday: '2000-11-02', // 出生日期
height: 170, // 身高
weight: 60, // 体重
email: 'keliq@example.com', // 邮箱
phone: '18888888888', // 电话
hobbies: ['football', 'singing'], // 兴趣爱好
}
那么首先就要根据这个结构来设计表单,按照惯例,先把表单的空架子搭好:
jsx
<ProForm onFinish={values => console.log(values)}>
{/* 选择合适的表单项 */}
</ProForm>
然后针对每个字段,选择一种合适的表单项。在 procomponents 中,表单项有很多种:
对于一名资深的前端开发来说,判断字段用哪个表单组件是一件非常容益的事情,我们可以很快得到下面的结论:
- 姓名:
ProFormText
- 性别:
ProFormRadio.Group
- 出生日期:
ProFormDatePicker
- 身高体重:
ProFormDigit
- 邮箱电话:
ProFormText
于是,收集用户信息的表单分分钟就做出来了:
jsx
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>
)
}
效果如下:
静态数组和动态数组
细心的同学肯定发现还缺少一项「兴趣爱好」,这个字段是一个数组,这个应该怎么做呢?有两种场景:
- 静态数组:只允许添加指定数量的兴趣项
- 动态数组:用户可以动态添加各种兴趣项
对于第一种场景,可以用 ProFormFieldSet
组件,它可以指定固定数量的表单项:
jsx
<ProFormFieldSet name="hobbies" label="兴趣爱好">
<ProFormText placeholder="请输入兴趣爱好1" />
<ProFormText placeholder="请输入兴趣爱好2" />
<ProFormText placeholder="请输入兴趣爱好3" />
</ProFormFieldSet>
效果如下:
而对于第二种场景,就不得不提到强大的 ProFormList
组件了,不仅支持动态删减表单项,还支持嵌套的对象结构,例如下面的效果:
用 ProFormList
实现的代码是:
jsx
<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
表单中拿到的值是一个对象数组:
处理依赖项
学会了如何在表单中收集数组项之后,我们再来增加一下复杂度:增加婚姻状态选项(未婚、已婚、离异、丧偶),如果用户选择已婚,在下面联动出现一个配偶姓名的表单项。
那这个需求应该怎么做呢?答案是 ProFormDependency
组件,为了简化起见,做了只有三个项目的表单:
jsx
<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>
效果如下:
只有当「婚姻状态」字段选择了「已婚」的时候,才展示「配偶姓名」字段。
编辑时回填表单
在很多场景中,用户提交表单之后,还可以继续查看和编辑表单,我们就需要从接口中获取数据,然后回填到表单当中,怎么处理呢?其实非常简单,只需要给 ProForm
添加 initialValues
选项即可,示例代码:
jsx
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 来开发表单的基础知识都已经讲完了,能够覆盖大部分的业务场景,赶快在自己的项目中练习一下吧!