vee-validate 用于 表单状态管理和交互:
vee-validate 是 Vue 生态中用于表单验证的库,它负责表单的状态管理、错误处理和交互逻辑。它可以与 zod 配合使用,来管理表单的验证逻辑和 UI 反馈。
vee-validate 提供了一个 useForm 钩子,用于管理表单的验证、提交等操作,并且可以与其他验证库(如 zod)结合使用来进行规则验证。
vee-validate+yup示例
1. 安装依赖
首先,确保你安装了 vee-validate 和 yup,如果还没有安装,可以使用以下命令:
npm install vee-validate yup
2. 创建一个 Vue 表单组件
假设我们有一个包含多个字段的表单,例如:用户名、电子邮件和密码。我们可以使用 vee-validate 进行表单验证,并使用 yup 定义验证规则。
<template>
<div>
<h1>注册表单</h1>
<form @submit="handleSubmit(onSubmit)" novalidate>
<div>
<label for="username">用户名:</label>
<input
id="username"
v-model="username"
type="text"
name="username"
:class="{'is-invalid': errors.username}"
/>
<span v-if="errors.username" class="error">{{ errors.username }}</span>
</div>
<div>
<label for="email">电子邮件:</label>
<input
id="email"
v-model="email"
type="email"
name="email"
:class="{'is-invalid': errors.email}"
/>
<span v-if="errors.email" class="error">{{ errors.email }}</span>
</div>
<div>
<label for="password">密码:</label>
<input
id="password"
v-model="password"
type="password"
name="password"
:class="{'is-invalid': errors.password}"
/>
<span v-if="errors.password" class="error">{{ errors.password }}</span>
</div>
<div>
<button type="submit" :disabled="isSubmitting">提交</button>
</div>
</form>
</div>
</template>
<script>
import { defineComponent, ref } from 'vue';
import { useForm, useField, FieldValues } from 'vee-validate';
import * as yup from 'yup';
export default defineComponent({
setup() {
// 定义表单字段
const { handleSubmit, reset, setErrors, isSubmitting, errors } = useForm({
validationSchema: yup.object({
username: yup
.string()
.required('用户名是必填项')
.min(3, '用户名必须至少包含 3 个字符'),
email: yup
.string()
.required('电子邮件是必填项')
.email('请输入有效的电子邮件地址'),
password: yup
.string()
.required('密码是必填项')
.min(8, '密码必须至少包含 8 个字符'),
}),
});
// 提交表单
const onSubmit = (values) => {
console.log(values);
// 在这里可以处理提交逻辑
};
return {
handleSubmit,
onSubmit,
isSubmitting,
errors,
};
},
});
</script>
<style scoped>
.error {
color: red;
}
.is-invalid {
border-color: red;
}
</style>
useForm: 使用 vee-validate 中的 useForm 钩子来管理表单状态、验证规则等。
validationSchema: 使用 yup 定义的验证规则对象来进行表单验证。
handleSubmit: 提交表单时,会触发表单验证。如果验证失败,errors 对象将包含错误信息。
isSubmitting: 控制表单提交按钮是否禁用。
使用 zod 进行表单验证
zod 是一个简单且强大的类型安全验证库,与 yup 类似,但它提供了更好的 TypeScript 支持。它在表单验证时比 yup 更强类型,可以提供更好的开发体验。
1. 安装 zod
首先,安装 zod 库:npm install zod
2. 配置 zod 验证
我们可以将 zod 与 vee-validate 结合使用,下面是一个使用 zod 进行表单验证的示例。
<template>
<div>
<h1>注册表单</h1>
<form @submit="handleSubmit(onSubmit)" novalidate>
<div>
<label for="username">用户名:</label>
<input
id="username"
v-model="username"
type="text"
name="username"
:class="{'is-invalid': errors.username}"
/>
<span v-if="errors.username" class="error">{{ errors.username }}</span>
</div>
<div>
<label for="email">电子邮件:</label>
<input
id="email"
v-model="email"
type="email"
name="email"
:class="{'is-invalid': errors.email}"
/>
<span v-if="errors.email" class="error">{{ errors.email }}</span>
</div>
<div>
<label for="password">密码:</label>
<input
id="password"
v-model="password"
type="password"
name="password"
:class="{'is-invalid': errors.password}"
/>
<span v-if="errors.password" class="error">{{ errors.password }}</span>
</div>
<div>
<button type="submit" :disabled="isSubmitting">提交</button>
</div>
</form>
</div>
</template>
<script>
import { defineComponent, ref } from 'vue';
import { useForm } from 'vee-validate';
import { z } from 'zod';
export default defineComponent({
setup() {
const { handleSubmit, reset, setErrors, isSubmitting, errors } = useForm({
validationSchema: z.object({
username: z
.string()
.min(3, '用户名必须至少包含 3 个字符')
.nonempty('用户名是必填项'),
email: z
.string()
.email('请输入有效的电子邮件地址')
.nonempty('电子邮件是必填项'),
password: z
.string()
.min(8, '密码必须至少包含 8 个字符')
.nonempty('密码是必填项'),
}),
});
const onSubmit = (values) => {
console.log(values);
// 在这里可以处理提交逻辑
};
return {
handleSubmit,
onSubmit,
isSubmitting,
errors,
};
},
});
</script>
<style scoped>
.error {
color: red;
}
.is-invalid {
border-color: red;
}
</style>
zod 和 yup 的比较
类型安全: zod 提供了更强的类型安全支持,适合 TypeScript 项目,能够自动推导出类型。
语法: zod 的语法较为简洁,且没有像 yup 那样的对象嵌套,需要时可以直接使用方法链式调用。
验证方式: zod 支持同步和异步验证,但不如 yup 在异步验证方面灵活,适用于一般的场景。