Joi 表单验证时如何动态添加校验规则?
我用 Joi 做前端表单验证,但有个字段的校验规则要根据另一个字段的值动态变化。比如当“用户类型”是“企业”时,“公司名称”才必填。试过在 schema 里用 Joi.when(),但一直报错说方法不存在,是不是我用法不对?
这是我的代码:
const schema = Joi.object({
userType: Joi.string().valid('individual', 'company').required(),
companyName: Joi.string().when('userType', {
is: 'company',
then: Joi.required(),
otherwise: Joi.optional()
})
});
第一步是确认你的 Joi 版本。Joi.when() 方法确实存在,但你需要确保使用的是支持这个语法的版本(至少 10.0.0 以上)。如果你用的是老版本,升级一下先。
假设你用的是最新版本,我们来看代码的问题。Joi.when() 需要一个完整的规则定义作为参数,而不是直接调用方法链。让我给你一个修正后的版本:
这里有几点要注意:
1. 使用
Joi.ref('userType')来引用其他字段的值2. 在 then 和 otherwise 分支中都要重新定义字段类型
3. 如果想验证更多复杂逻辑,可以在 when 中嵌套多个条件
原理上,Joi 的 when 方法其实就是个条件判断器。它会先检查目标字段(这里是 userType)的值是否符合某个条件,如果符合条件就应用 then 规则,否则用 otherwise 规则。这和编程中的 if-else 逻辑差不多。
举个更复杂的例子:如果我们还需要验证当用户类型是 "vip" 时也要必填公司名称,可以这样写:
希望这些解释能帮到你。说实话,表单验证这种东西虽然简单,但要做到灵活确实需要些技巧,慢慢来就好。
when语法需要特别注意一些细节。我来帮你优化一下这段代码,这样更清晰也更容易维护。首先,
Joi.when()需要完整的引用路径,而且then和otherwise里面的规则要完整定义。这里有个更优雅的写法:注意到几个地方:在
then和otherwise里面都显式定义了Joi.string(),并且用了allow('')来允许空值。这样处理企业用户时能正常校验,而个人用户可以不填这个字段。有时候这种动态规则确实让人头疼,调试时记得打印出错误信息看看具体问题在哪。希望这能帮到你。