从 JSON 创建动态 Yup 验证模式
Create dynamic Yup validation schema from JSON
我正在尝试在我的 React 表单中使用 Yup
和 Formik
。表单字段将是动态的,它们的验证也是如此。
export const formData = [
{
id: "name",
label: "Full name",
placeholder: "Enter full name",
type: "text",
required: true,
value: "User name",
values: [],
validations: [
{
type: "minLength",
value: "5",
error_message: "name should be atleast 5 char long"
},
{
type: "maxLength",
value: "10",
error_message: "name should be atleast 5 char long"
}
]
},
{
id: "email",
label: "Email",
placeholder: "Email",
type: "text",
required: true,
value: "email",
values: [],
validations: [
{
type: "minLength",
value: "5",
error_message: "name should be atleast 5 char long"
},
{
type: "maxLength",
value: "10",
error_message: "name should be atleast 5 char long"
},
{
type: "email",
error_message: "Valid email"
}
]
},
{
id: "phoneNumber",
label: "phone number",
type: "text",
required: true,
value: "7878787878",
values: [],
validations: [
{
type: "minLength",
value: "5",
error_message: "name should be atleast 5 char long"
},
{
type: "maxLength",
value: "10",
error_message: "name should be atleast 5 char long"
},
{
type: "required",
error_message: "phone number is required"
}
]
},
{
id: "total",
label: "Total People in Family",
placeholder: "family members count",
type: "text",
required: false,
value: "1",
values: [],
validations: [
{
type: "minLength",
value: "1",
error_message: "there should be atleast 1 family member"
},
{
type: "maxLength",
value: "5",
error_message: "max family members can be 5"
}
]
}
]
let validateSchema = yup.object().shape({
name: yup.string().required("name is required"),
email: yup.string().email(),
phoneNumber: yup.number().min(10, "minium 10 numbers"),
total: yup
.number()
.min(1, "minium 1 member")
.max(5, "max 5 member")
.required("member is required") });
- 我目前正在做的是遍历上述数组并调用相应的 React 表单组件。
- 验证目前由
Yup
处理。我知道您可以像上面的“validateSchema”变量一样创建静态 Yup 验证模式。
- 现在我想根据值创建此验证模式
在
formData.validation
数组中。我尝试了一些方法
codesandbox 还是想不通。另外,我看了
进入 Yup.lazy
,但它似乎让我很困惑。
任何帮助将不胜感激:)
以防有人试图即时创建 yupschema
。在一些帮助下,我能够做到。
import * as yup from "yup";
export function createYupSchema(schema, config) {
const { id, validationType, validations = [] } = config;
if (!yup[validationType]) {
return schema;
}
let validator = yup[validationType]();
validations.forEach(validation => {
const { params, type } = validation;
if (!validator[type]) {
return;
}
console.log(type, params);
validator = validator[type](...params);
});
schema[id] = validator;
return schema;
}
如果您正在寻找更多功能,请考虑 schema-to-yup。
但是@vijayscode 的回答非常方便。这是扩展他们的示例以包含 when
条件的尝试:
import * as yup from "yup";
function createYupSchema(schema, config) {
const { id, validationType, validations = [] } = config;
if (!yup[validationType]) {
return schema;
}
let validator = yup[validationType]();
validations.forEach((validation) => {
const { params, type } = validation;
if (!validator[type]) {
return;
}
if (type === "when") {
const { is, then, otherwise } = params[1];
let whenParams = {};
whenParams.is = is;
whenParams.then = (schema) => schema[then[0].type](...then[0].params);
if (otherwise) {
whenParams.otherwise = (schema) =>
schema[otherwise[0].type](...otherwise[0].params);
}
validator = validator["when"](params[0], whenParams);
} else {
validator = validator[type](...params);
}
});
schema[id] = validator;
return schema;
}
并像这样定义您的配置:
const myConfig = [
{
id: "isBig",
validationType: "boolean",
},
{
id: "count",
validationType: "number",
validations: [
{
type: "when",
params: [
"isBig",
{
is: true,
then: [
{
type: "min",
params: [5],
},
],
otherwise: [
{
type: "min",
params: [0],
},
],
},
],
},
],
},
];
const schema = myConfig.reduce(createYupSchema, {});
const validateSchema = yup.object().shape(schema);
我正在尝试在我的 React 表单中使用 Yup
和 Formik
。表单字段将是动态的,它们的验证也是如此。
export const formData = [
{
id: "name",
label: "Full name",
placeholder: "Enter full name",
type: "text",
required: true,
value: "User name",
values: [],
validations: [
{
type: "minLength",
value: "5",
error_message: "name should be atleast 5 char long"
},
{
type: "maxLength",
value: "10",
error_message: "name should be atleast 5 char long"
}
]
},
{
id: "email",
label: "Email",
placeholder: "Email",
type: "text",
required: true,
value: "email",
values: [],
validations: [
{
type: "minLength",
value: "5",
error_message: "name should be atleast 5 char long"
},
{
type: "maxLength",
value: "10",
error_message: "name should be atleast 5 char long"
},
{
type: "email",
error_message: "Valid email"
}
]
},
{
id: "phoneNumber",
label: "phone number",
type: "text",
required: true,
value: "7878787878",
values: [],
validations: [
{
type: "minLength",
value: "5",
error_message: "name should be atleast 5 char long"
},
{
type: "maxLength",
value: "10",
error_message: "name should be atleast 5 char long"
},
{
type: "required",
error_message: "phone number is required"
}
]
},
{
id: "total",
label: "Total People in Family",
placeholder: "family members count",
type: "text",
required: false,
value: "1",
values: [],
validations: [
{
type: "minLength",
value: "1",
error_message: "there should be atleast 1 family member"
},
{
type: "maxLength",
value: "5",
error_message: "max family members can be 5"
}
]
}
]
let validateSchema = yup.object().shape({
name: yup.string().required("name is required"),
email: yup.string().email(),
phoneNumber: yup.number().min(10, "minium 10 numbers"),
total: yup
.number()
.min(1, "minium 1 member")
.max(5, "max 5 member")
.required("member is required") });
- 我目前正在做的是遍历上述数组并调用相应的 React 表单组件。
- 验证目前由
Yup
处理。我知道您可以像上面的“validateSchema”变量一样创建静态 Yup 验证模式。 - 现在我想根据值创建此验证模式
在
formData.validation
数组中。我尝试了一些方法 codesandbox 还是想不通。另外,我看了 进入Yup.lazy
,但它似乎让我很困惑。
任何帮助将不胜感激:)
以防有人试图即时创建 yupschema
。在一些帮助下,我能够做到。
import * as yup from "yup";
export function createYupSchema(schema, config) {
const { id, validationType, validations = [] } = config;
if (!yup[validationType]) {
return schema;
}
let validator = yup[validationType]();
validations.forEach(validation => {
const { params, type } = validation;
if (!validator[type]) {
return;
}
console.log(type, params);
validator = validator[type](...params);
});
schema[id] = validator;
return schema;
}
如果您正在寻找更多功能,请考虑 schema-to-yup。
但是@vijayscode 的回答非常方便。这是扩展他们的示例以包含 when
条件的尝试:
import * as yup from "yup";
function createYupSchema(schema, config) {
const { id, validationType, validations = [] } = config;
if (!yup[validationType]) {
return schema;
}
let validator = yup[validationType]();
validations.forEach((validation) => {
const { params, type } = validation;
if (!validator[type]) {
return;
}
if (type === "when") {
const { is, then, otherwise } = params[1];
let whenParams = {};
whenParams.is = is;
whenParams.then = (schema) => schema[then[0].type](...then[0].params);
if (otherwise) {
whenParams.otherwise = (schema) =>
schema[otherwise[0].type](...otherwise[0].params);
}
validator = validator["when"](params[0], whenParams);
} else {
validator = validator[type](...params);
}
});
schema[id] = validator;
return schema;
}
并像这样定义您的配置:
const myConfig = [
{
id: "isBig",
validationType: "boolean",
},
{
id: "count",
validationType: "number",
validations: [
{
type: "when",
params: [
"isBig",
{
is: true,
then: [
{
type: "min",
params: [5],
},
],
otherwise: [
{
type: "min",
params: [0],
},
],
},
],
},
],
},
];
const schema = myConfig.reduce(createYupSchema, {});
const validateSchema = yup.object().shape(schema);