async-validator
这是一个异步表单验证插件,参考于: https://github.com/freeformsystems/async-validate
API
以下内容修改自早期async-validate的版本。
Usage
基本用法: 定义一个 对象
形式的验证规则的描述符(descriptor)
, 并将它作为参数传入 schema
, 得到一个 验证器(validator)
, 验证器(validator)
调用 validate()
方法, 来验证是否符合规则.
var schema = require('async-validator');
var descriptor = {
name: {type: "string", required: true}
}
var validator = new schema(descriptor);
validator.validate({name: "muji"}, (errors, fields) => {
if(errors) {
// 验证失败, errors是一个包含所有错误的数组
// fields is an object keyed by field name with an array of
// errors per field
return handleErrors(errors, fields);
}
// 验证通过
});
Validate
function(source, [options], callback)
-
source
: 要验证的对象 (必须). -
options
: 描述验证选项的对象(可选) . -
callback
: 验证完成时的回调函数 (必须).
Options
-
first
: Boolean, 当第一个验证规则出错时直接调用回调函数, 不再进行后面的验证.如果验证涉及到多个异步调用(比如数据库查询),我们只需要第一次错误, 这时就可以使用这个设置
firstFields
: Boolean|String[], 当指定字段的第一个验证规则出错时调用回调函数,验证终止。 true表示验证所有字段。
Rules
rules 可能是执行验证的函数。
function(rule, value, callback, source, options)
-
rule
: 这个 rule 对应于需要验证的数据中的信息。需要验证的字段名被赋值给“field”属性, -
value
: 这个 value 是正在验证数据中属性的值 -
callback
: 验证完成后回调函数. 它希望传递一个错误实例数组来指示验证失败。 -
source
:validate
方法传递过来的需要验证的对象 -
options
: 额外选项 -
options.messages
: 这个对象包含验证错误信息, 它将与defaultMessages
深度结合
将包含函数的验证规则描述符(descriptor) 传递给 schema
并返回 validator
var schema = require('async-validator');
var descriptor = {
name(rule, value, callback, source, options) {
var errors = [];
if(!/^[a-z0-9]+$/.test(value)) {
errors.push(
new Error(
util.format("%s must be lowercase alphanumeric characters",
rule.field)));
}
callback(errors);
}
}
var validator = new schema(descriptor);
validator.validate({name: "Firstname"}, (errors, fields) => {
if(errors) {
return handleErrors(errors, fields);
}
// 验证通过
});
对一个字段进行多个验证也是比较常见的情况, 可以定义一个对象数组来完成这种操作, 例如:
var descriptor = {
email: [
{type: "string", required: true, pattern: schema.pattern.email},
{validator(rule, value, callback, source, options) {
var errors = [];
// 如果数据库中已经存在此email地址
// 那么就在验证错误的数组中添加一个错误
callback(errors);
}}
]
}
Type
指明需要验证的类型:
-
string
: Must be of typestring
.默认类型
-
number
: Must be of typenumber
. -
boolean
: Must be of typeboolean
. -
method
: Must be of typefunction
. -
regexp
: Must be an instance ofRegExp
or a string that does not generate an exception when creating a newRegExp
. -
integer
: Must be of typenumber
and an integer. -
float
: Must be of typenumber
and a floating point number. -
array
: Must be an array as determined byArray.isArray
. -
object
: Must be of typeobject
and notArray.isArray
. -
enum
: Value must exist in theenum
. -
date
: Value must be valid as determined byDate
-
url
: Must be of typeurl
. -
hex
: Must be of typehex
. -
email
: Must be of typeemail
.
Required
required 表明字段必须是被验证的对象的。
Pattern
pattern说明使用正则表达式,该表达式必须匹配才能通过验证。
Range
range是使用min和max属性定义的。string和array,对length进行比较。number类型则是值在min和max之间。
Length
要验证字段的确切长度,请指定len属性。对于string和array类型比较是在length属性上执行的,对于number类型来说,这个属性表示一个精确匹配的数字,也就是说,它可能只与len严格相等。
如果len属性与min和max range属性相结合,len优先。
Enumerable
为了从一个列表中验证一个值,使用enum类型的enum属性列出该字段的有效值,例如:
var descriptor = {
role: {type: "enum", enum: ['admin', 'user', 'guest']}
}
Whitespace
当 whitespace
为 true
, 并且类型必须是 string
, 那么将只包含空格的必需字段视为错误。
您可能希望对用户输入进行过滤,而不是对空白进行测试,请参阅transform,以获得允许您删除空白的示例。
Deep Rules
如果你需要验证多层对象属性,可以通过将嵌套规则分配给规则的字段属性来验证 string
或 array
类型。
var descriptor = {
address: {
type: "object", required: true,
fields: {
street: {type: "string", required: true},
city: {type: "string", required: true},
zip: {type: "string", required: true, len: 8, message: "invalid zip"}
}
},
name: {type: "string", required: true}
}
var validator = new schema(descriptor);
validator.validate({ address: {} }, (errors, fields) => {
// errors for address.street, address.city, address.zip
});
需要注意的是, 如果在父规则上, 没有 required
属性设置为 true
, 那么子规则不会生效
Deep rule validation creates a schema for the nested rules so you can also specify the options
passed to the schema.validate()
method.
var descriptor = {
address: {
type: "object", required: true, options: {single: true, first: true},
fields: {
street: {type: "string", required: true},
city: {type: "string", required: true},
zip: {type: "string", required: true, len: 8, message: "invalid zip"}
}
},
name: {type: "string", required: true}
}
var validator = new schema(descriptor);
validator.validate({ address: {} }, (errors, fields) => {
// now only errors for street
});
如果有一组子规则, 父规则同样生效:
var descriptor = {
roles: {
type: "array", required: true, len: 3,
fields: {
0: {type: "string", required: true},
1: {type: "string", required: true},
2: {type: "string", required: true}
}
}
}
若需要检测的内容为: {roles:[“admin”,“user”]}
,则会有两个错误。 一个用于数组长度不匹配,另一个用于索引2处缺少的所需数组条目。
defaultField
defaultField属性可与数组或对象类型一起使用,以验证容器的所有值。 它可以是包含验证规则的对象或数组。 例如:
var descriptor = {
urls: {
type: "array", required: true,
defaultField: {type: "url"}
}
}
请注意,defaultField扩展于field,请参阅deep rules。
Transform
有时候需要对需要检验的值进行转换, 比如需要强转类型, 或者清理空格. 这时候需要用到 transform
函数. 属性在验证之前进行转换,并重新分配给源对象,以便更改属性的值。
var schema = require('async-validator');
var sanitize = require('validator').sanitize;
var descriptor = {
name: {
type: "string",
required: true, pattern: /^[a-z]+$/,
transform(value) {
return sanitize(value).trim();
}
}
}
var validator = new schema(descriptor);
var source = {name: " user "};
validator.validate(source, (errors, fields) => {
assert.equal(source.name, "user");
});
如果没有 transform
函数,验证将会失败,原因是模式不匹配,因为输入的值包含前后空格,但是通过添加 transform
函数验证将会通过,同时对字段值剔除空格。
Messages
当验证不通过的时候, 需要不同的提示消息
最简单的方式就是在rule中添加一个 message
的值:
{name:{type: "string", required: true, message: "Name is required"}}
message
可以是任何类型, 例如下面是 jsx 格式:
{name:{type: "string", required: true, message: <b>Name is required</b>}}
对于不同的语言,您可能需要相同的模式验证规则,在这种情况下,为每种语言复制模式规则是没有意义的。
在这个场景中,您可以为该语言提供自己的消息,并将其分配给模式:
var schema = require('async-validator');
var cn = {
required: '%s 必填',
};
var descriptor = {name:{type: "string", required: true}};
var validator = new schema(descriptor);
// 将defaultMessages深度结合
validator.messages(cn);
...
如果要定义自己的验证函数,最好将消息字符串分配给一个messages对象,然后通过 options.messages
访问。
validator
你可以为指定字段自定义验证函数:
const fields = {
asyncField:{
validator(rule,value,callback){
ajax({
url:'xx',
value:value
}).then(function(data){
callback();
},function(error){
callback(new Error(error))
});
}
},
promiseField:{
validator(rule, value){
return ajax({
url:'xx',
value:value
});
}
}
};
FAQ
如何避免警告
var Schema = require('async-validator');
Schema.warning = function(){};
Test Case
npm test
npm run chrome-test
Coverage
npm run coverage
open coverage/ dir
License
Everything is MIT.