是的动态验证链

Cor*_*rey 5 javascript yup

我正在使用 yup 验证并尝试构建一个条件验证对象。

我的问题是,如何在没有硬编码的情况下将所需的和匹配的对象添加到 Yup.string() 对象。类似于链接 jQuery 函数的方式。

这是我试图实现的一个例子:

if (field.required) {
  valSchema[id] = Yup.string().required(errorText[id].default);
}
if (field.validation) {
  valSchema[id] = Yup.string().matches(re, field.validation[0].message);
}
if (field.otherValidation) {
  valSchema[id] = Yup.string().matches(re, field.validation[1].message);
}
Run Code Online (Sandbox Code Playgroud)

显然这是行不通的,因为最后一个条件为真会覆盖前一个条件。

那么如果所有条件都为真,最终结果会是这样。

valSchema[id] = Yup.string()
  .required(errorText[id].default)
  .matches(reExp, field.validation[0].message);
  .matches(reExp1, field.validation[1].message);
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

谢谢。

joe*_*une 1

要有条件地添加/验证,您可以使用 Yup 的.when方法。

此方法可以基于正在验证的值添加条件验证,或者通过context可以作为选项参数传递给.validate.isValid调用的对象。

我创建了以下代码的简化示例。context该解决方案利用在验证期间传入的Yup对象。使用符号引用上下文对象的键$

const schema = yup.object({
  name: yup.string()
    .when('$required', (required, schema) => (required ? schema.required() : schema))
    .when('$regex1', (regex1, schema) => (regex1 ? schema.matches(/j/) : schema))
    .when('$regex2', (regex2, schema) => (regex2 ? schema.matches(/oe/) : schema))
});
Run Code Online (Sandbox Code Playgroud)

提供以下对象作为上下文将为您提供问题中所有条件均成立的最终结果:

{
  required: true,
  regex1: true,
  regex2: true,
}
Run Code Online (Sandbox Code Playgroud)

将它们放在一起可以得到以下工作示例:

const yup = require("yup");

const schema = yup.object({
  name: yup.string()
    .when('$required', (required, schema) => (required ? schema.required() : schema))
    .when('$regex1', (regex1, schema) => (regex1 ? schema.matches(/j/) : schema))
    .when('$regex2', (regex2, schema) => (regex2 ? schema.matches(/oe/) : schema))
});

const myObject = {
  name: "joe",
}

const name = await schema.validate(myObject, {
  context: {
    required: true,
    regex1: true,
    regex2: true,
  }
});

console.log(name); // { name: "joe" }
Run Code Online (Sandbox Code Playgroud)

在此处查看和测试 RunKit 上的实时代码:https ://runkit.com/joematune/6138a7db98ff810008ef37ab