vee-validate中的验证定义细节:
discountName: string().required(), //这个required没加额外信息,默认就是,验证提示就是 discountName is a required field
discountName: string().required("ha ha"), // 这个required加了提示信息,验证提示就是 ha ha, 这会覆盖默认的msg,即使加了label也会被覆盖,discountName: string().required("ha ha").label("name"), 最后还是 ha ha.
discountName: string().required().label("name"), //这个required没加额外信息,但是加了label信息,验证提示就是 name is a required field
其它验证细节:
//yup条件验证 when的使用
1.单条件
vatCountries: array().when("displayPaymentMethods", {
is: true,
then: schema => schema.test(
"at-least-one-vat-country",
verifyHint.fieldRequired,
(value) => value.length > 0,
),
otherwise: schema => schema.notRequired(),
}),
vat: number().when("displayPaymentMethods", {
is: true,
then: schema => schema.required(verifyHint.fieldRequired),
otherwise: schema => schema.notRequired(),
}),
2.多条件(同时满足,需要解构)
invoiceReceiverInformation: string().when(
["displayPaymentMethods", "isWireTransfer"],
{
is: ([displayPaymentMethods, isWireTransfer]) => displayPaymentMethods && isWireTransfer,
then: (schema) => schema.required(verifyHint.fieldRequired),
otherwise: (schema) => schema.notRequired(),
}
)
多条件(任意一个满足,下面这个只是一个特例,其实最好不要这么用)
invoiceReceiverInformation: string().when(
["displayPaymentMethods", "isWireTransfer"],
{
is: true,
then: (schema) => schema.required(verifyHint.fieldRequired),
otherwise: (schema) => schema.notRequired(),
}
)
3.使用字符串
paymentMethod: string().when("paymentType", {
is: "credit_card",
then: (schema) => schema.required("Credit card details are required"),
otherwise: (schema) => schema.notRequired(),
});
或者
someField: string().when("otherField", {
is: value => {
console.log(value); // 需要打印值
return value === "someValue"; // 需要 return
},
then: schema => schema.required("Required"),
});
源码:
type ConditionConfig<T extends ISchema<any>> = {
is: any | ((...values: any[]) => boolean);
then?: (schema: T) => ISchema<any>;
otherwise?: (schema: T) => ISchema<any>;
};
可以知道 is 字段支持两种类型:
直接传入值(例如 true、false、字符串等)
传入一个函数(可接收多个 values 并返回 boolean)
//数组验证
vee-validate 提供了 useFieldArray 这个 API,专门用于处理 数组类型的表单字段,比如 动态添加或删除输入项。
使用示例:
<script setup lang="ts">
import { useFieldArray } from "vee-validate";
const { fields: reminders, push, remove } = useFieldArray<{ message: string }>("reminders");
// 添加一项
const addReminder = () => {
push({ message: "" });
};
// 删除一项
const deleteReminder = (index: number) => {
remove(index);
};
</script>
<template>
<div v-for="(reminder, index) in reminders" :key="reminder.key">
<input v-model="reminder.value.message" placeholder="Enter reminder" />
<button @click="deleteReminder(index)">Delete</button>
</div>
<button @click="addReminder">Add Reminder</button>
</template>
实际使用示例(单独定义验证层):
const {
fields: reminders,
push,
remove,
replace,
} = useFieldArray<RegistrationPaymentsReminder>("reminders");
代码分析:
reminders 绑定到 表单字段 reminders(即数组)
push(item) 新增一项
remove(index) 删除某一项
replace(newArray) 替换整个数组
useFieldArray 核心特点
fields 是一个响应式数组,每个项都有 key 和 value:
{ key: Symbol(), value: { message: "" } }
还有个问题,如果有多个 useFieldArray 需要区分push这些,可以按照下面几种方式定义:
1.分别定义多个useFieldArray, 给 push remove 等操作取名字, 上面的其实使用的默认名称 push remove 等, 适用于逻辑不同的
<script setup lang="ts">
import { useFieldArray } from "vee-validate";
// 处理 reminders
const { fields: reminders, push: pushReminder, remove: removeReminder } =
useFieldArray<{ message: string }>("reminders");
// 处理 notifications
const { fields: notifications, push: pushNotification, remove: removeNotification } =
useFieldArray<{ title: string }>("notifications");
// 添加 reminder
const addReminder = () => {
pushReminder({ message: "" });
};
// 添加 notification
const addNotification = () => {
pushNotification({ title: "" });
};
// 删除 reminder
const deleteReminder = (index: number) => {
removeReminder(index);
};
// 删除 notification
const deleteNotification = (index: number) => {
removeNotification(index);
};
</script>
<template>
<div>
<h3>Reminders</h3>
<div v-for="(reminder, index) in reminders" :key="reminder.key">
<input v-model="reminder.value.message" placeholder="Reminder" />
<button @click="deleteReminder(index)">Delete</button>
</div>
<button @click="addReminder">Add Reminder</button>
</div>
<div>
<h3>Notifications</h3>
<div v-for="(notification, index) in notifications" :key="notification.key">
<input v-model="notification.value.title" placeholder="Notification" />
<button @click="deleteNotification(index)">Delete</button>
</div>
<button @click="addNotification">Add Notification</button>
</div>
</template>
2.集中定义,适用于逻辑类似的
<script setup lang="ts">
import { useFieldArray } from "vee-validate";
const fieldArrays = {
reminders: useFieldArray<{ message: string }>("reminders"),
notifications: useFieldArray<{ title: string }>("notifications"),
};
// 添加项
const addItem = (fieldName: keyof typeof fieldArrays, item: any) => {
fieldArrays[fieldName].push(item);
};
// 删除项
const removeItem = (fieldName: keyof typeof fieldArrays, index: number) => {
fieldArrays[fieldName].remove(index);
};
</script>
<template>
<div>
<h3>Reminders</h3>
<div v-for="(reminder, index) in fieldArrays.reminders.fields" :key="reminder.key">
<input v-model="reminder.value.message" placeholder="Reminder" />
<button @click="removeItem('reminders', index)">Delete</button>
</div>
<button @click="addItem('reminders', { message: '' })">Add Reminder</button>
</div>
<div>
<h3>Notifications</h3>
<div v-for="(notification, index) in fieldArrays.notifications.fields" :key="notification.key">
<input v-model="notification.value.title" placeholder="Notification" />
<button @click="removeItem('notifications', index)">Delete</button>
</div>
<button @click="addItem('notifications', { title: '' })">Add Notification</button>
</div>
</template>
