每天对自己多问几个为什么,总是有着想象不到的收获。 一个菜鸟小白的成长之路(copyer)
前言
在开发项目中,经常使用表单模块,来完成交互的过程。但是我感觉,在以前开发的过程中,就是直接copy
,没有仔细的去理解其中的逻辑,只要现象满足就可以。但是最近项目中想封装一个通用的表单组件,还是必要知道其中的逻辑和各个属性。所以,就回头过来仔细的理一下。
使用
在antd4
中,使用form表单,有着三种不同的方式的写法。
- 普通用法 (所以的布局全在表单中)
- hooks写法 (主要是针对函数式组件,外面的按钮可以触发表单的中的事件)
- class写法 (跟hooks的思路是一样的,不过它是通过
ref
来获取的)
这里就主要理一下前面的两种写法。
1、普通的写法
const onFinish = (values) => {
// 点击提交按钮,拿到表单中的数据
console.log(values);
}
<Form
name="basic"
labelCol={
{
span: 9 }}
wrapperCol={
{
span: 15 }}
initialValues={
{
username: 'james' }}
onFinish={
onFinish}
onValuesChange={
onValuesChange}
layout="inline"
>
<Form.Item
label="username"
name="username"
rules={
[{
required: true, message: 'Please input your username!' }]}
>
<Input />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">确定</Button>
</Form.Item>
</Form>
写法优点: 简便,可读性强
写法缺点: 所有的东西都写在Form里面,外面的逻辑不能操作。提交按钮,还需要写上htmlType="submit"
,还必须被Form.Item
包裹。
2、hook写法
export default function StudyForm() {
//使用antd4中的提供的hooks
const [ form ] = Form.useForm()
const onFinish = (values) => {
console.log(values);
}
const onClick = () => {
// 外面的结构调用表单内部的方法,然后出发onFinish
form.submit()
}
return (
<>
<Form
name="basic"
form={
form} // 注册
labelCol={
{
span: 9 }}
wrapperCol={
{
span: 15 }}
initialValues={
{
username: 'james' }}
onFinish={
onFinish}
layout="inline"
>
<Form.Item
label="username"
name="username"
colon
rules={
[{
required: true, message: 'Please input your username!' }]}
>
<Input />
</Form.Item>
</Form>
<Button type="primary" onClick={
onClick}>确定</Button>
</>
);
}
写法优点:写法更加的灵活,扩展性更强
写法缺点: 需要对form提供的API有所认知
Form实例提供的API
名称 | 说明 | 类型 |
---|---|---|
getFieldError | 获取对应字段名的错误信息 | (name: NamePath) => string[] |
getFieldInstance | 获取对应字段实例 | (name: NamePath) => any |
getFieldsError | 获取一组字段名对应的错误信息,返回为数组形式 | (nameList?: NamePath[]) => FieldError[] |
getFieldsValue | 获取一组字段名对应的值,会按照对应结构返回。默认返回现存字段值,当调用 getFieldsValue(true) 时返回所有值 |
(nameList?: NamePath[], filterFunc?: (meta: { touched: boolean, validating: boolean }) => boolean) => any |
getFieldValue | 获取对应字段名的值 | (name: NamePath) => any |
isFieldsTouched | 检查一组字段是否被用户操作过,allTouched 为 true 时检查是否所有字段都被操作过 |
(nameList?: NamePath[], allTouched?: boolean) => boolean |
isFieldTouched | 检查对应字段是否被用户操作过 | (name: NamePath) => boolean |
isFieldValidating | 检查对应字段是否正在校验 | (name: NamePath) => boolean |
resetFields | 重置一组字段到 initialValues |
(fields?: FieldData[]) => void |
scrollToField | 滚动到对应字段位置 | (name: NamePath, options: [ScrollOptions]) => void |
setFields | 设置一组字段状态 | (fields: FieldData[]) => void |
setFieldsValue | 设置表单的值 | (values) => void |
submit | 提交表单,与点击 submit 按钮效果相同 |
() => void |
validateFields | 触发表单验证 | (nameList?: NamePath[]) => Promise |
属性解释
Form
1、props
labelCol、wrapperCol
是用来对表单进行布局,跟Col的用法是一致的
initialValues
使用用来初始化表单数据的(只在初始化,或者重置的时候生效)
layout
表单布局 (垂直、水平)2、方法
onFinish
点击提交按钮时,触发
onValuesChange
改变表单中的数据,就触发(主要通知父组件做出改变)
Form.Item
props
name
给表单每项取个名字,通过该字段拿取数据
rules
验证规则
当然属性还有很多,需要用的时候再去查看文档就行了
总结
总的来说,对表单的写法有着基本的认识,不会像以前那么的迷茫了,在未来也有更加的熟悉hooks的写法。