6

我正在使用 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);
}

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

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

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

有任何想法吗?

谢谢。

4

1 回答 1

0

要有条件地添加/验证,可以使用 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))
});

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

{
  required: true,
  regex1: true,
  regex2: true,
}

将它们放在一起为您提供以下工作示例:

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" }

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

于 2021-09-08T13:09:24.813 回答