
本文详细阐述了 Yup 库从旧版本(如 0.26.x)升级到新版本(如 1.x)后,`when` 方法在条件验证语法上的主要变化。重点解决了旧版中 `is` 属性不再被支持的问题,并提供了使用函数式回调进行条件判断的新方法,帮助开发者顺利迁移并正确实现复杂的表单验证逻辑。
在现代前端开发中,表单验证是不可或缺的一环。Yup 作为一款强大的 JavaScript 模式验证库,因其简洁的 API 和灵活的验证能力,在 React 等框架中广受欢迎。然而,随着 Yup 库的不断迭代更新,其 API 也可能发生变化,这在版本升级时会给开发者带来一些挑战。本文将聚焦于 Yup 从旧版本(如 0.26.x)升级到新版本(如 1.x)后,when 条件验证方法的核心语法变更,特别是旧版中 is 属性不再被支持的问题,并提供相应的解决方案。
在 Yup 的早期版本中,when 方法允许开发者根据另一个字段的值来条件性地应用验证规则。其语法通常采用一个对象字面量,其中包含 is、then 和 otherwise 属性,用于定义条件和对应的验证模式。
考虑以下一个典型的旧版 Yup 验证模式,它根据 enabled 字段的布尔值来决定 hostname 字段是否需要验证:
import * as Yup from 'yup'; // 假设 Yup 已导入
// 辅助函数,包含正则表达式定义
const helpers = {
regEx: {
domainName: /^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/
}
};
const { domainName } = helpers.regEx;
export default Yup.object({
enabled: Yup.boolean(),
hostname: Yup.string().when('enabled', {
is: true, // 旧版语法,判断 enabled 是否为 true
then: Yup.string()
.matches(domainName, '请提供一个完全限定域名')
.required('您必须提供主机名'),
otherwise: Yup.string().notRequired(),
}),
});当尝试将包含上述代码的项目从 Yup 0.26.x 升级到 1.x 版本时,编译器会抛出以下错误:
No overload matches this call.
Overload 1 of 4, '(keys: string | string[], builder: ConditionBuilder<StringSchema<string, AnyObject, undefined, "">>): StringSchema<string, AnyObject, undefined, "">', gave the following error.
Argument of type '{ is: boolean; then: Yup.StringSchema<string, Yup.AnyObject, undefined, "">; otherwise: Yup.StringSchema<string, Yup.AnyObject, undefined, "">; }' is not assignable to parameter of type 'ConditionBuilder<StringSchema<string, AnyObject, undefined, "">>'.
Object literal may only specify known properties, and 'is' does not exist in type 'ConditionBuilder<StringSchema<string, AnyObject, undefined, "">>'.这个错误信息明确指出,传入 when 方法的第二个参数(一个对象字面量)与期望的类型 ConditionBuilder 不匹配,并且最关键的是,is 属性在 ConditionBuilder 类型中不再存在。这意味着 Yup 1.x 版本已经移除了通过 is 属性来定义条件的方式。
在 Yup 1.x 及更高版本中,when 方法变得更加灵活,它不再接受一个包含 is 属性的对象,而是期望一个回调函数作为其第二个参数。这个回调函数负责接收依赖字段的值,并根据这些值返回相应的验证模式。
回调函数的签名通常是 ([dependentValue], schema) => Schema:
这种函数式的方法提供了更大的灵活性,可以实现更复杂的条件逻辑。
让我们将前面提到的 hostname 验证逻辑,从旧版语法重构为 Yup 1.x 支持的新版函数式回调语法。
import * as Yup from 'yup';
const helpers = {
regEx: {
domainName: /^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/
}
};
const { domainName } = helpers.regEx;
export default Yup.object({
enabled: Yup.boolean(),
hostname: Yup.string().when('enabled', ([enabled], schema) => {
// enabled 是一个数组,因为 'enabled' 是字符串数组的简写形式
// 如果只有一个依赖字段,可以安全地取第一个元素
if (enabled) { // 判断 enabled 字段的值是否为 true (或存在)
return schema
.matches(domainName, '请提供一个完全限定域名')
.required('您必须提供主机名');
}
return schema.notRequired();
}),
});在这个新的实现中:
新版 when 方法的函数式回调对于处理字符串或枚举类型的条件也同样强大。例如,根据 marital_status(婚姻状况)字段的值来决定 companion_name(伴侣姓名)字段是否必填。
假设 marital_status 的值可以是 'C' (已婚), 'D' (同居), 'E' (订婚) 或其他(单身,离异等)。只有当婚姻状况为 'C', 'D', 'E' 时,伴侣姓名才需要填写。
import * as Yup from 'yup';
export const userSchema = Yup.object({
marital_status: Yup.string().required('请选择婚姻状况'),
companion_name: Yup.string().when('marital_status', ([marital_status], schema) => {
// 定义需要伴侣姓名的婚姻状态列表
const requiresCompanionName = ['C', 'D', 'E'];
// 检查当前的 marital_status 是否在列表中
if (requiresCompanionName.includes(marital_status)) {
return schema
.trim() // 移除前后空格
.min(2, '伴侣姓名至少需要2个字符')
.required('请提供伴侣姓名');
}
return schema.notRequired();
}),
// 其他字段...
});这个例子清晰地展示了如何利用回调函数内的 JavaScript 逻辑来处理更复杂的条件判断,例如使用 Array.prototype.includes() 方法。
// 示例:依赖两个字段
Yup.string().when(['fieldA', 'fieldB'], ([valueA, valueB], schema) => {
if (valueA === 'someValue' && valueB > 10) {
return schema.required();
}
return schema.notRequired();
});Yup 1.x 版本对 when 方法的语法更新,从 is 属性的对象字面量转向了函数式回调,这代表了一种更灵活、更强大的条件验证范式。虽然这要求开发者适应新的编码风格,但它也使得处理复杂依赖和动态验证逻辑变得更加直观和可维护。通过理解并掌握这种新的函数式方法,开发者可以更高效地构建健壮且用户友好的表单验证系统。在进行 Yup 版本升级时,务必注意这些语法变化,并根据本文提供的指南进行相应的代码调整。
以上就是Yup when 方法语法更新指南:解决 is 属性不再支持的问题的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号