Yup
官方解释:
Yup is a JavaScript schema builder for value parsing and validation. Define a schema, transform a value to match, validate the shape of an existing value, or both. Yup schema are extremely expressive and allow modeling complex, interdependent validations, or value transformations.
大致译为:
Yup
是一个用于值解析和验证的JavaScript
架构构建器。 定义模式、转换值以匹配、验证现有值的形状,或两者兼而有之。Yup
模式具有极强的表现力,允许对复杂的、相互依赖的验证或值转换进行建模。
Schema
schema
是对数据的一种描述。例:yup.string()
描述数据是字符串类型。我们可以 required
、min
,max
等修饰方法对其进行修饰,也可以使用 test
方法来订制更复杂的描述。
除了 string
,yup
还内置了 number
、boolean
、data
、array
、object
模式,它们都继承于 mixed
模式。通过 mixed
我们可以对 schema
进行订制 。
依据使用的方式将 schema
大致划分为以下两大类 schema types
和 schema types
。
type schema
type schema
主要包含有 mixed、string、number、boolean、date、array、object 等。
yup.mixed()
mixed.cast()
mixed.cast(value: any, options = {}): any
尝试将传入的值强制转换为与模式匹配的值,转换失败的话可能返回 null
、NaN
或其他字符信息。
示例:
// 数字类型 1 将会转化为字符串 '1'
yup.string().min(2).required().cast(1)
mixed.when()
mixed.when(keys: string | Array<string>, builder: object | (value, schema)=> Schema): Schema
通过同级或同级子字段作为判定条件来对其他字段匹配 schema
。
示例:
// 方式一:is~then/otherwise 形式
let schema = object({
isBig: boolean(),
count: number()
.when('isBig', {
// is: (val) => val == true,
is: true,
then: yup.number().min(5), // isBig 为 true 时 count 使用该 schema
otherwise: yup.number().min(0), // isBig 不为 true 时 count 使用该 schema
})
// $other 可以替换 options 参数内 context 对象中的值
.when('$other', (other, schema) => (other === 4 ? schema.max(6) : schema)), // schema.max(6) 生效
});
// 方式二:回调函数形式
let schema = yup.object({
isBig: yup.boolean(),
count: yup.number().when('isBig', (isBig, schema) => {
return isBig ? schema.min(5) : schema.min(0);
}),
});
await schema.validate({ isBig: true, count: 4 }, { context: { other: 4 } });
mixed.test()
mixed.test(name: string, message: string | function, testFun: function): Schema
向验证链添加测试函数。在投射任何对象后运行测试定制特定逻辑的验证提示信息。
testFun function
- 普通函数
function (val) {}
- 箭头函数
(val, context) => {}
说明:测试函数为普通函数上下文对象为 函数内 this
;为箭头函数上下文对象为函数第二个参数 context
。
context type
type ContextType = {
path: string // 当前验证的路径字符串
schema: object // 测试运行所针对的解析模式对象
options: object // 调用 validate() 或 isValid() 的选项对象
parent: object // 嵌套模式下父对象的值
originalValue: any // 验证的源数据信息
createError: { path: string; message: string; params: object } // 创建并返回验证错误
}
示例:
// 提示信息中的 path 变量见上面 ContextType 对象属性说明
// 同步校验
let jerrySchema = yup.string().require('名称不能为空').test(
'isJerry',
'${path}名称不正确,不是 Jerry', // 默认错误提示信息【回调函数返回 false 时使用】
(val, context) => {
if (val !== 'Jerry') {
// 提示 createError 创建的错误信息【将覆盖默认错误信息提示】
retrun context.createError({
message: '名称不正确,不是 Jerry',
})
}
return true;
}
)
// 异步校验
let asyncJerrySchema = yup.string().require('名称不能为空').test(
'isJerry',
'${path}名称不正确,不是 Jerry', // 默认错误提示信息
async (val, context) => {
const res = await fetch('/isJerry/' + val);
// true 存在校验通过,false 时不存在显示默认错误提示信息
return res.data;
}
)
await jerrySchema.isValid('Jerry'); // => true
await asyncJerrySchema.isValid('Tom'); // => false
yup.array()
array.of()
array.of(type: Schema): Schema
指定数组元素的架构。 of()
是可选的,当省略时,数组模式将不会验证其内容。
示例:
let schema = yup.array().of(
// yup.object({...}) 与 yup.object().shape({...}) 在这等同,详情见下文 yub.object().shape()
yup.object().shape({
name: yup
.string().trim()
.max(50, '不能超过 50 字符')
.required('姓名不能为空')
.test(
'name',
'名称不正确,不是 Jerry',
(val) => val === 'Jerry'
),
age: yup.number().min(0, '年龄不能小于 0').required('年龄不能为空')
})
)
await schema.validate([{ name: 'Arvinjun', age: 18 }]);
yup.object()
object.shape()
object.shape(fields: object, noSortEdges?: Array<[string, string]>): Schema
定义对象的键和所述键的模式。 请注意,您可以链接形状方法,其作用类似于对象扩展。
示例:
object({
a: string(),
b: number(),
}).shape({
b: string(),
c: number(),
});
// 等同于
object({
a: string(),
b: string(),
c: number(),
});
method schema
method schema
主要包含有 reach
、addMethod
、ref
、lazy
、ValidtionError
等。
lazy()
yup.lazy((value: any) => Schema): Lazy
创建在验证/转换时评估的架构。对于为多态字段和数组创建递归模式(如树)很有用。
注意 ⚠️:在定义父子递归对象模式时,您需要将子对象的 default()
重置为 undefined
, 否则当您强制转换对象时,对象将会无限嵌套!
示例:
let node = object({
id: number(),
child: yup.lazy(() => node.default(undefined)),
});
let renderable = yup.lazy((val) => {
switch (typeof val) {
case 'number':
return number();
case 'string':
return string();
default:
return mixed();
}
});
let renderables = array().of(renderable);