对多个值进行验证

问题描述 投票:0回答:7

我想在 formik 中使用 yup 验证我的表单。假设我有 4 个字段 A、B、C、D,它们都是字符串。如果我希望至少有一个字段不为空,那么我应该如何编写验证模式,那么这是一种有效的形式?提前致谢!

formik yup
7个回答
47
投票

使用 Yup 时,如果所有正常功能都失败了,您可以使用

.test
功能,记录在此处 - https://github.com/jquense/yup#mixedtestname-string-message-string--function-test-function -架构

mixed.test(name: string, message: string | function, test: function): Schema

向验证链添加测试功能。在投射任何对象后运行测试。许多类型都内置了一些测试,但您可以轻松创建自定义测试。为了允许异步自定义验证,所有(或没有)测试都是异步运行的。这样做的结果是无法保证测试执行顺序。

对于您的实施,您需要为 4 个字段中的每一个编写一个“测试”,以确保这 4 个字段中的一个不为空。

field1: yup
    .string()
    .test(
      'oneOfRequired',
      'One of Field1, Field2, Field3 or Field4 must be entered',
      function(item) {
        return (this.parent.field1 || this.parent.field2 || this.parent.field3 || this.parent.field4)
      }
    ),
field2: yup
    .string()
    .test(
      'oneOfRequired',
      'One of Field1, Field2, Field3 or Field4 must be entered',
      function(item) {
        return (this.parent.field1 || this.parent.field2 || this.parent.field3 || this.parent.field4)
      }
    ),

等...

请注意,在这种情况下,我没有使用箭头功能。这是因为要使用“this”上下文,您必须使用此语法,Yup 文档中提到了这一点。


14
投票

如果您不想将验证添加到每个字段,而是为这些事情设置一个“全局”错误处理程序,还有另一种可能性。

你会做这样的事情:

const schema = yup.object().shape({
    field1: yup.string().required(),
    field2: yup.string().required(),
    field3: yup.string().required(),
    field4: yup.string().required(),
}).test('yourTestCondition', function (value) {
    // your global test code...
})


6
投票

您正在搜索的内容有一个解决方案。您可以只为父元素编写一个测试,而不是为每个元素编写一个测试。模拟全局错误。

yup.object({
field1: yup.string(), 
field2: yup.string(),
field3: yup.string(),
field4: yup.string(),
})
.test('global-ok',
      'you do not fulfill the requirements',
      function (value) {
        return CONDITION OVER THE CHILDREN;
      })
      
      

比如不想写一系列必填元素的错误,只给出一种全局错误。你可以:

    yup.object({
    username: yup.string().required(), 
    password: yup.string().required(),
    email: yup.string().required().test(verify_email),
    })
    .test('global-ok',
          'The data is not correct',
          function (value) {
            return username && password && email;
          })
          


5
投票

这是一个把事情放在上下文中的例子

考虑只有当他/她来自美国并且超过 10 年时才需要学生姓名,对于这种情况,这就是我们可以编写 yup 配置的方式。

注意:多个字段用于验证

const formSchema = yup.object({
    age: yup.number(),
    country: yup.string(),
    studentName: yup.string().when(['age', 'country'], {
        is: (age: string, country: string) => {
            if (age > 10) {
                return true // validate and check next condition
            }
            if (country === 'USA') {
                return true // validate and go to then function
            } else return false // for all other cases studentName is not required
        },
        then: (schema) =>
            schema
            .required("Student name is required")
    })

})


2
投票
                email: Yup.string()
                    .when([‘, 'showEmail’, ’anotherField’], {
                        is: (showEmail, anotherField) => {
                            return (showEmail && anotherField);
                        },
                        then: Yup.string().required('Must enter email address')
                    }),

多个字段也可以用于验证。 处理多个参数的最简单方法


2
投票

如果你更喜欢 ES6 并且想使用 arrow functionsJamie answer answer 的修改版本是这样的:

field1: yup
    .string()
    .test(
      'oneOfRequired',
      'One of Field1, Field2, Field3 or Field4 must be entered',
      (item,testContext)=>{
        return (testContext.parent.field1 || testContext.parent.field2 || testContext.parent.field3 || testContext.parent.field4)
      }
    ),
field2: yup
    .string()
    .test(
      'oneOfRequired',
      'One of Field1, Field2, Field3 or Field4 must be entered',
      (item,testContext)=> {
        return (testContext.parent.field1 || testContext.parent.field2 || testContext.parent.field3 || testContext.parent.field4)
      }
    ),

有关详细信息,官方文档.


0
投票
lazy(value => {
        switch (typeof value) {
          case 'array':
            return array().of(string()).nullable();
          case 'string':
            return string().nullable();
          default:
            return array().of(string()).nullable();
        }
      }),
© www.soinside.com 2019 - 2024. All rights reserved.