Zod Schema Validation
If you prefer to use zod for schema validation instead of yup, you can do so with the @vee-validate/zod
package.
With @vee-validate/zod
you can use Zod
typed schemas as drop-in replacements for yup
schemas.
Install
To use this plugin, make sure to install these packages vee-validate
, zod
, and @vee-validate/zod
.
shyarn add vee-validate zod@beta @vee-validate/zod
# or with NPM
npm install vee-validate zod@beta @vee-validate/zod
Validating with Zod
You can create validation schemas for either field-level validation or form-level validation, the @vee-validate/zod
exposes two functions that transform Zod's schemas into something that can be understood by vee-validate
main core and use them to perform validation.
Field-level Validation
The first function is toFieldValidator
, which accepts a Zod schema. You can use the converted schema by passing it to the rules
prop present on the <Field />
component:
vue<template>
<Form>
<Field name="email" type="email" :rules="fieldSchema" />
<ErrorMessage name="email" />
</Form>
</template>
<script setup>
import { Field, Form, ErrorMessage } from 'vee-validate';
import { toFieldValidator } from '@vee-validate/zod';
import * as zod from 'zod';
const fieldSchema = toFieldValidator(zod.string().nonempty('Field is required').email('Must be a valid email'));
</script>
If you prefer to use the Composition API, then you can pass the converted schema to the useField
function:
vue<template>
<input name="email" v-model="value" type="email" />
<span>{{ errorMessage }}</span>
</template>
<script setup>
import { useField } from 'vee-validate';
import { toFieldValidator } from '@vee-validate/zod';
import * as zod from 'zod';
const fieldSchema = toFieldValidator(
zod.string().nonempty('Field is required').email({ message: 'Must be a valid email' })
);
const { value, errorMessage } = useField('email', fieldSchema);
</script>
Form-Level Validation
You can also use Zod's zod.object
to create validation schemas for your forms instead of individually passing it for each field, this is covered in general in the form-level validation section.
To be able to use zod.object
to define form schemas, you need to use another function with is appropriately named toFormValidator
.
The toFormValidator
function accepts a Zod object schema and prepares it to be consumed by the vee-validate validation logic.
You can pass the converted schema to the validation-schema
prop present on the <Form />
component:
vue<template>
<Form :validation-schema="validationSchema" @submit="onSubmit">
<Field name="email" type="email" />
<ErrorMessage name="email" />
<Field name="password" type="password" />
<ErrorMessage name="password" />
<button>Submit</button>
</Form>
</template>
<script setup>
import { Form, Field, ErrorMessage } from 'vee-validate';
import { toFormValidator } from '@vee-validate/zod';
import * as zod from 'zod';
const validationSchema = toFormValidator(
zod.object({
email: zod.string().nonempty('This is required').email({ message: 'Must be a valid email' }),
password: zod.string().nonempty('This is required').min(8, { message: 'Too short' }),
})
);
function onSubmit(values) {
alert(JSON.stringify(values, null, 2));
}
</script>
Alternatively, if you prefer to use the composition API, you can pass the converted schema as the validationSchema
option accepted by the useForm
function:
vue<template>
<form @submit="onSubmit">
<input name="email" v-model="email" type="email" />
<span>{{ errors.email }}</span>
<input name="password" v-model="password" type="password" />
<span>{{ errors.password }}</span>
<button>Submit</button>
</form>
</template>
<script setup>
import { useField, useForm } from 'vee-validate';
import { toFormValidator } from '@vee-validate/zod';
import * as zod from 'zod';
const validationSchema = toFormValidator(
zod.object({
email: zod.string().nonempty('This is required').email({ message: 'Must be a valid email' }),
password: zod.string().nonempty('This is required').min(8, { message: 'Too short' }),
})
);
const { handleSubmit, errors } = useForm({
validationSchema,
});
const { value: email } = useField('email');
const { value: password } = useField('password');
const onSubmit = handleSubmit(values => {
alert(JSON.stringify(values, null, 2));
});
</script>
TypeScript Form Values Inference
vee-validate will try to do its best to infer the types of the form values if you are using the composition API, vee-validate can infer the types of the form values when you provide either a yup
or a converted zod
validation schema.
tsconst validationSchema = toFormValidator(
zod.object({
email: zod.string().nonempty('This is required').email({ message: 'Must be a valid email' }),
age: zod.number().min(8, { message: 'Too smol' }),
})
);
const { handleSubmit, errors } = useForm({
validationSchema,
initialValues: {
// You get auto-completion and type check for `email` and `age` properties
},
});
// You will get auto-completion for possible errors for `email` and `age`
errors.email;
const onSubmit = handleSubmit(values => {
// Values will be typed as { email: string; age: number; }
});