我在 reactjs 中使用 formik 进行表单管理,我有一个关于 yup 验证的问题。
我有两个字段,一个是选择国家的选择控件,另一个是邮政编码。
在国家/地区数组中,我们有验证邮政编码的正则表达式,其想法是使用当前所选国家的正则表达式验证输入的邮政编码,有人可以提供有关如何执行此操作的线索。
需要数值不能高于其他两个字段值的乘积的字段示例
const validationSchema = Yup.object().shape({
num1: Yup.number().positive().required('This field is required.'),
num2: Yup.number().positive().required('This field is required.'),
num3: Yup.number().positive().required('This field is required.')
.when(['num1', 'num2'], (num1, num2, schema) => {
return num1 > 0 && num2 > 0 ? schema.max(num1 / num2) : schema.max(0);
})
});
下面是一个将日期选择器的结束日期强制为after
开始日期的示例:
const schema = Yup.object().shape({
start_date: Yup.date()
.typeError('Start Date is required')
.required('Start Date is required'),
end_date: Yup.date()
.typeError('End Date is required')
.required('End Date is required')
.when('start_date', (start_date) => {
if (start_date) {
return Yup.date()
.min(start_date, 'End Date must be after Start Date')
.typeError('End Date is required')
}
}),
})
需要if
在表单加载时放入语句以正确验证,并且还需要typeError
在选择开始日期但尚未结束日期时放入规则以正确验证。
重要的是你可以看到when
; 第一个参数是要检查的字段,第二个参数是返回 Yup 验证对象的验证函数。
我试图只返回 true 或 false,但它似乎会抛出错误,所以它比纯粹的验证函数要复杂一些。
let schema = object({
isBig: boolean(),
count: number()
.when('isBig', {
is: true, // alternatively: (val) => val == true
then: yup.number().min(5),
otherwise: yup.number().min(0),
})
});
使用.when()
并传递一个函数,该函数根据国家/地区的值返回邮政编码的模式。
我有同样的问题。我是一个能够用来when
解决它的。
import { object, string } from 'yup';
const validCountries = ['US', 'CA'];
const zipRegexes = {
US: /^\d{5}(?:-?\d{4})?$/,
CA: /^[ABCEGHJKLMNPRSTVXY]\d[A-Z]\d[A-Z]\d$/
};
const addressSchema = object().shape({
country: string()
.oneOf(validCountries, 'Please select a country from the list above')
.required('Please select a country from the list above'),
/* Other fields
.
.
.
*/
zip: string()
.trim()
.required('Required')
.transform(value => value.toUpperCase())
.when('country', (country, schema) => {
if (
string()
.oneOf(validCountries)
.required()
.isValid(country)
) {
return schema.matches(
zipRegexes[country],
`not a valid ${country} zip code`
);
}
return schema;
})
});
您可以通过解构父类来访问任何表单字段的值 const { country } = this.parent;
const yup = require("yup");
const schema = yup.object({
country: yup.object().required("This field is required"),
zipcode: yup
.string()
.required("This field is required")
.test("is-right-zipcode", "Invalid zipcode", function(code) {
const { country } = this.parent;
return code.match(country.regex);
})
});
您可以根据字段数组进行条件验证。以下示例仅在未指定field6
至少一项时才需要。field1 - field5
let schema = object({
field1: Yup.bool(),
field2: Yup.bool(),
field3: Yup.bool(),
field4: Yup.bool(),
field5: Yup.bool(),
field6: Yup.bool().when(
[
'field1',
'field2',
'field3',
'field4',
'field5',
],
{
is: (...fields) => fields.some(Boolean),
then: Yup.bool().notRequired(),
otherwise: Yup.bool().required(),
}
),
});