在一些 Web 应用中,表单处理起来比其他功能模块都麻烦,很多体力活,往往在数据的校验会很费时间,自从我用了schema-typed (github.com/rsuite/sche… 这个工具,发现很多场景变得异常简单。
安装
npm install schema-typed --save
示例
import { SchemaModel, StringType, DateType, NumberType, ObjectType, ArrayType } from 'schema-typed';
const model = SchemaModel({
username: StringType().isRequired('Username required'),
email: StringType().isEmail('Email required'),
age: NumberType('Age should be a number').range(18, 30, 'Over the age limit'),
tags: ArrayType().of(StringType('The tag should be a string').isRequired()),
role: ObjectType.shape({
name: StringType().isRequired('Name required'),
permissions: ArrayType().isRequired('Permissions required')
})
});
const checkResult = model.check({
username: 'foobar',
email: 'foo@bar.com',
age: 40,
tags: ['Sports', 'Games', 10],
role: { name: 'administrator' }
});
console.log(checkResult);
示例代码的返回结构如下:
{
username: { hasError: false },
email: { hasError: false },
age: { hasError: true, errorMessage: 'Over the age limit' },
tags: {
hasError: true,
array: [
{ hasError: false },
{ hasError: false },
{ hasError: true, errorMessage: 'The tag should be a string' }
]
},
role: {
hasError: true,
object: {
name: { hasError: false },
permissions: { hasError: true, errorMessage: 'Permissions required' }
}
}
};
数据多重验证
StringType()
.minLength(6, "Can't be less than 6 characters")
.maxLength(30, 'Cannot be greater than 30 characters')
.isRequired('This field required');
数据自定义验证
我们可以通过一个 addRule 函数来自定义某些规则;还可以通过 pattern 方法设置一个正则表达式进行自定义验证
const model = SchemaModel({
field1: StringType().addRule((value, data) => {
return /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(value);
}, 'Please enter legal characters'),
field2: StringType().pattern(/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/, 'Please enter legal characters')
});
model.check({ field1: '', field2: '' });
/**
{
field1: {
hasError: true,
errorMessage: 'Please enter legal characters'
},
field2: {
hasError: true,
errorMessage: 'Please enter legal characters'
}
};
**/
数据多字段交互验证
如下例子是用来验证两个密码是否一致
const model = SchemaModel({
password1: StringType().isRequired('This field required'),
password2: StringType().addRule((value, data) => {
if (value !== data.password1) {
return false;
}
return true;
}, 'The passwords are inconsistent twice')
});
model.check({ password1: '123456', password2: 'root' });
/**
{
password1: { hasError: false },
password2: {
hasError: true,
errorMessage: 'The passwords are inconsistent twice'
}
}
**/
异步检查
如下例子用来验证邮箱是否重复
function asyncCheckEmail(email) {
return new Promise(resolve => {
setTimeout(() => {
if (email === 'foo@domain.com') {
resolve(false);
} else {
resolve(true);
}
}, 500);
});
}
const model = SchemaModel({
email: StringType()
.isEmail('Please input the correct email address')
.addRule((value, data) => {
return asyncCheckEmail(value);
}, 'Email address already exists')
.isRequired('This field cannot be empty')
});
model.checkAsync({ email: 'foo@domain.com' }).then(checkResult => {
console.log(checkResult);
/**
{
email: {
hasError: true,
errorMessage: 'Email address already exists'
}
};
**/
});
验证嵌套对象
验证嵌套对象,这些对象可以使用ObjectType()方法定义。例如:
const model = SchemaModel({
id: NumberType().isRequired('This field required'),
name: StringType().isRequired('This field required'),
info: ObjectType().shape({
email: StringType().isEmail('Should be an email'),
age: NumberType().min(18, 'Age should be greater than 18 years old')
})
});
const user = {
id: 1,
name: '',
info: { email: 'schema-type', age: 17 }
};
model.check(data);
/**
{
"id": { "hasError": false },
"name": { "hasError": true, "errorMessage": "This field required" },
"info": {
"hasError": true,
"object": {
"email": { "hasError": true, "errorMessage": "Should be an email" },
"age": { "hasError": true, "errorMessage": "Age should be greater than 18 years old" }
}
}
}
*/
组合校验
SchemaModel提供了一个静态方法组合,可以与多个SchemaModel组合,以返回一个新的SchemaModel。
const model1 = SchemaModel({
username: StringType().isRequired('This field required'),
email: StringType().isEmail('Should be an email')
});
const model2 = SchemaModel({
username: StringType().minLength(7, "Can't be less than 7 characters"),
age: NumberType().range(18, 30, 'Age should be greater than 18 years old')
});
const model3 = SchemaModel({
groupId: NumberType().isRequired('This field required')
});
const model4 = SchemaModel.combine(model1, model2, model3);
model4.check({
username: 'foobar',
email: 'foo@bar.com',
age: 40,
groupId: 1
});
常用的API
具体详细用法可以参照资料:github.com/rsuite/sche…
- SchemaModel
- StringType
- NumberType
- ArrayType
- DateType
- ObjectType
- BooleanType