深入掌握ant-design的form异步校验(一)
一、前言
本文基于开源项目:
https://github1s.com/ant-design/ant-design
https://github.com/yiminghe/async-validator
很多小伙伴对antd的form表单校验不是很清楚,有些时候写了一些校验规则然后不是自己想要实现的效果、或者不清楚校验规则是什么无从写起。
下面我们一起来学习学习form的校验~
二、validateFields
广东靓仔从文档找了个demo,代码如下:
<Form form={form} initialValues={{ aaa: '2' }}>
<Form.Item name="aaa">
<Input
onChange={async () => {
await sleep(0);
try {
await form.validateFields();
} catch (e) {
// do nothing
}
}}
/>
</Form.Item>
<Form>
我们来看看validateFields的返回示例:
validateFields()
.then(values => {
/*
values:
{
username: 'username',
password: 'password',
}
*/
})
.catch(errorInfo => {
/*
errorInfo:
{
values: {
username: 'username',
password: 'password',
},
errorFields: [
{ name: ['password'], errors: ['Please input your Password!'] },
],
outOfDate: false,
}
*/
});
AntDesign的表单校验是基于async-validator,是支持异步校验的。
三、async-validator介绍
官方介绍:Validate form asynchronous.
简单理解:async-validator是一个表单的异步验证的第三方库。
安装
npm i async-validator
使用
它基本用法包括定义描述符,将它分配给模式并将要验证的对象和回调函数传递给validate模式的方法:
import Schema from 'async-validator';
const descriptor = {
name: {
type: 'string',
required: true,
validator: (rule, value) => value === 'muji',
},
age: {
type: 'number',
asyncValidator: (rule, value) => {
return new Promise((resolve, reject) => {
if (value < 18) {
// reject错误信息
reject('too young');
} else {
resolve();
}
});
},
},
};
const validator = new Schema(descriptor);
validator.validate({ name: 'muji' }, (errors, fields) => {
if (errors) {
// 验证失败,errors 是一个包含所有错误的数组
// fields 是一个以字段名称为键的对象
// errors per field
return handleErrors(errors, fields);
}
// 这里则是验证通过
});
// PROMISE USAGE
validator.validate({ name: 'muji', age: 16 }).then(() => {
// 验证通过或没有错误消息
}).catch(({ errors, fields }) => {
return handleErrors(errors, fields);
});
简单梳理下:传入验证规则对象,可以新建一个验证器对象。验证器对象的validate方法用于验证数据是否符合验证规则。
Validate有三个参数:
source:要验证的对象(必需)。
options:描述验证处理选项的对象(可选)。
callback:验证完成时调用的回调函数(可选)。
可以看出Validate返回了一个Promise 对象
rules规则
function(rule, value, callback, source, options)
rule:源描述符中的验证规则,对应于正在验证的字段名称。它总是被分配一个field带有被验证字段名称的属性。
value:正在验证的源对象属性的值。
callback:验证完成后调用的回调函数。它期望传递一个Error实例数组来指示验证失败。如果检查是同步的,可以直接返回一个falseorError或Error Array。
source:传递给validate方法的源对象。
options:其他选项。
options.messages:包含验证错误消息的对象,将与 defaultMessages 深度合并。
传递给validate或asyncValidate传递给验证函数的选项,以便在验证函数中引用瞬态数据(例如模型引用)。但是,保留了一些选项名称;如果使用选项对象的这些属性,它们将被覆盖。保留的属性messages是exception和error。
我们经常写rules为对象数组,针对单个字段的多个验证规则进很有用:
const descriptor = {
email: [
{ type: 'string', required: true, pattern: Schema.pattern.email },
{
validator(rule, value, callback, source, options) {
const errors = [];
// 测试邮箱地址是否已经存在于数据库中
// 如果确实则将验证错误添加到错误数组
return errors;
},
},
],
};
type类型
可以使用的类型如下:
string: 必须是类型string。This is the default type.
number: 必须是类型number。
boolean: 必须是类型boolean。
method: 必须是类型function。
regexp: 必须是RegExp创建新的时不产生异常的实例或字符串RegExp。
integer: 必须是类型number和整数。
float: 必须是类型number和浮点数。
array: 必须是由 确定的数组Array.isArray。
object: 必须是 typeobject而不是Array.isArray。
enum: 值必须存在于enum.
date:值必须是有效的,由Date
url: 必须是类型url。
hex: 必须是类型hex。
email: 必须是类型email。
any: 可以是任何类型。
asyncValidator异步验证器
我们可以自定义指定字段的异步验证功能,代码如下:
const fields = {
asyncField: {
asyncValidator(rule, value, callback) {
ajax({
url: 'xx',
value: value,
}).then(function(data) {
callback();
}, function(error) {
callback(new Error(error));
});
},
},
promiseField: {
asyncValidator(rule, value) {
return ajax({
url: 'xx',
value: value,
});
},
},
};
validator验证器
我们可以为指定字段自定义验证功能,代码如下:
const fields = {
field: {
validator(rule, value, callback) {
return value === 'test';
},
message: 'Value is not equal to "test".',
},
field2: {
validator(rule, value, callback) {
return new Error(`${value} is not equal to 'test'.`);
},
},
arrField: {
validator(rule, value) {
return [
new Error('Message 1'),
new Error('Message 2'),
];
},
},
};
四、总结
在我们阅读完官方文档后,我们一定会进行更深层次的学习,比如看下框架底层是如何运行的,以及源码的阅读。
这里广东靓仔给下一些小建议:
在看源码前,我们先去官方文档复习下框架设计理念、源码分层设计
阅读下框架官方开发人员写的相关文章
借助框架的调用栈来进行源码的阅读,通过这个执行流程,我们就完整的对源码进行了一个初步的了解
接下来再对源码执行过程中涉及的所有函数逻辑梳理一遍
作者:广东靓仔
欢迎关注:前端早茶