使用

概念

验证链

每个 acr.string() 或者 acr.number() 这样的类型声明后面返回的都是一个 chain我们称之为 验证链 。它就像一个链条,声明了我们对这个字段的数据要进行的种种验证。而数据会在这个链条上依次验证,直到全部通过或者某个验证没有通过为止(前面的验证没有通过,后面的验证不会继续执行)。

await acr.string().min(2).max(5).equal('bar').validate('foobar');

在上面的例子中,验证链上分别有 3 个规则(min, max, equal),当到达第二个(max)时,foobar 字符数大于了 5,因此失败,而 equal 验证则不会执行。

数据验证

await acr.validate({
    foo: 'bar'
}, {
    foo: acr.string().min(2).max(5).equal('bar')
});

数据验证方法接受两个参数:

data: 用于验证的数据

rules: 验证规则

比如在 egg 中(推荐在 egg 中使用 egg-acr 插件),我们可以将 ctx 上的表单数据进行验证:

await acr.validate(ctx.request.body, {
    // rules
});

默认值

一些可选的参数常常拥有一个默认值,虽然实现并不复杂,但这无疑增加了代码的复杂程度,也不够优雅,因此,从 1.2.0 开始 acr 支持设置默认值。

const [ foo ] = await acr.validate({}, {
  foo: acr.string().default('bar'),
});

foo; // 'bar';

有时候,可能需要复杂的计算才能得出默认值:

const [ foo ] = await acr.validate({
  bax: 123,
}, {
  foo: acr.string().default((data, context) => {
    return data['bax'] === 123 ? 'bar' : 456;
  }),
});

foo; // 'bar';

数据转换

很多情况下,我们验证的数据就是即将使用的数据。为此,acr 提供了一个便捷的方式来获取数据和转换数据。

const { nickname, password } = await acr.validate({
    nickname: 'seek',
    password: 'secret'
}, {
    nickname: acr.string().max(12).transform(value => value + 'cx')
    password: acr.string({ 
            transform: value => value + 'salt'
        })
        .max(32);
});

console.log(nickname); // seekcx 
console.log(password); // secretsalt

转换函数的参数是一个 (value: any): Promise<any> 类型的闭包,闭包会得到一个 value,返回值会被作为最终数据。

上面的例子展示了两种对数据进行转换的方式:

第一种是在验证链上使用 transform ,第二种是在声明时使用配置的方式。除此之外,还可以在 配置 中声明 chians 来声明默认的转换,详细可以参考 配置

参数命名

有时候的验证的错误提示在某些场景显得不那么友好。比如:

await acr.validate({
    nickname: 'foobar',
}, {
    nickname: acr.string().max(5),
});

这种情况,大多数验证组件都会提示:nickname must be at most 5 characters 。这看起来似乎没有什么不对。但当我们把语言环境切换到 中文 时,这个错误会变为 nickname不能超过 5 个字符。这对用户来说十分奇怪,因为用户并不知道这个 nickname 什么意思。

为了解决这个问题,acr 支持给参数命名。

await acr.validate({
    nickname: 'foobar',
}, {
    nickname: acr.string('昵称').max(5),
});

这样,nickname不能超过 5 个字符就会变成 昵称不能超过 5 个字符

可能你会觉得,这样写的话,在英文条件下,不就变成了 昵称 must be at most 5 characters 吗?也并不友好啊。我们考虑过这种情况,认为这个不应该是 acr 处理的范围,acr 只负责提供这么一个功能,不能负责翻译其中的内容。因此,你可以在你的应用中使用国际化的方法自行转换。比如在 egg 中:

await acr.validate({
    nickname: 'foobar',
}, {
    nickname: acr.string(ctx.__('nickname')).max(5),
});

和数据转换一样,参数命名也支持配置的方式。参考 配置

错误模板

为了错误提示更加友好,基于 lodash 的 template,实现了一套简单的模板引擎。

"{ name || path } required"

模板中,变量以大括号 {} 作为分割,大括号里面的区域可以是任何 js 代码。

我们内置了一些与此验证相关的变量,可以直接在模板中使用:

  • name 参数名称,上文 参数命名 章节所设置的名称

  • path 参数路径,实际上是参数在数据中的 key,命名为 path 是为后续打算实现的嵌套深度验证功能做准备

  • params 此次验证传递的所有参数

Last updated