Appearance
VeeValidate
VeeValidate is a powerful form validation library for Vue.js that provides a comprehensive solution for handling form validation with minimal boilerplate code. It's designed to work seamlessly with Vue 3's Composition API, offering a declarative and flexible approach to form validation.
Key Features
- Composition API First: Built specifically for Vue 3's Composition API, providing composable functions for validation
- TypeScript Support: Full TypeScript support with type inference for better developer experience
- Schema Validation: Supports popular validation libraries like Yup, Zod, and Joi
- Field-level Validation: Validate individual fields with custom rules or schema validation
- Form-level Validation: Handle entire form validation with cross-field validation support
- Built-in Rules: Comes with common validation rules out of the box
- Async Validation: Support for asynchronous validation (server-side validation, debounced validation)
- Flexible Error Handling: Customizable error messages and error display patterns
Composition API
VeeValidate's Composition API approach centers around composable functions that you can use in your setup()
function or <script setup>
:
useField()
: For validating individual form fieldsuseForm()
: For managing entire forms and their validation stateuseFieldArray()
: For handling dynamic arrays of fieldsuseFormErrors()
: For accessing form-wide error statesuseFormValues()
: For accessing current form values reactively
This approach provides better composition, reusability, and integration with Vue 3's reactivity system compared to template-based validation approaches.
Example (My Xerius)
vue
<script setup lang="ts">
import { ref } from "vue";
import { useForm } from "vee-validate";
import { toTypedSchema } from "@vee-validate/zod";
import { z } from "zod";
import { XerButton, XerFormControl, XerInputText, xerArrowRight } from "@xerius/codey-components";
// const { t } = useI18n();
const props = defineProps<{
instellingenEmail?: string;
email?: string;
}>();
// const emit = ...
const validationSchema = toTypedSchema(
z.object({
emailInput: z
.string({ message: t("Error.Message.GeldigEmailAdres") })
.email({ message: t("Error.Message.GeldigEmailAdres") })
.max(255, { message: t("Error.Message.GeldigEmailAdres") }),
})
);
const { defineField, errors, handleSubmit, setFieldValue } = useForm({
validationSchema,
initialValues: {
emailInput: props.email,
},
});
const [emailInput, emailAttrs] = defineField("emailInput", {
validateOnModelUpdate: false,
});
const onSubmit = handleSubmit((values) => {
console.log(values);
// handle form submission...
});
</script>
<template>
<form @submit="onSubmit">
<XerFormControl
id="email"
:label="t('EmailAdres.Label')"
:caption="t('Toelichting')"
:invalid="!!errors.emailInput"
:error-message="errors.emailInput"
class="w-full"
>
<XerInputText
id="email"
v-model.trim="emailInput"
v-bind="emailAttrs"
type="email"
:invalid="!!errors.emailInput"
/>
</XerFormControl>
<XerButton variant="cta" :icon="xerArrowRight" type="submit" class="w-full mt-8">
{{ t("Opslaan.Label") }}
</XerButton>
</form>
</template>