一、前言
本文基于开源项目:
很多小伙伴对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
实例数组来指示验证失败。如果检查是同步的,可以直接返回一个false
orError
或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'), ]; }, }, };
四、总结
在我们阅读完官方文档后,我们一定会进行更深层次的学习,比如看下框架底层是如何运行的,以及源码的阅读。
这里广东靓仔给下一些小建议:
- 在看源码前,我们先去官方文档复习下框架设计理念、源码分层设计
- 阅读下框架官方开发人员写的相关文章
- 借助框架的调用栈来进行源码的阅读,通过这个执行流程,我们就完整的对源码进行了一个初步的了解
- 接下来再对源码执行过程中涉及的所有函数逻辑梳理一遍