Forms are tricky. They are one of the most common things you'll build in a web application, but also one of the most complex.
Well-designed HTML forms are:
- Well-structured and semantically correct.
- Easy to use and navigate (keyboard).
- Accessible with ARIA attributes and proper labels.
- Has support for client and server side validation.
- Well-styled and consistent with the rest of the application.
In this guide, we will take a look at building forms with vee-validate and zod. We're going to use a <FormField>
component to compose accessible forms using Radix Vue components.
Features
The <Form />
component is a wrapper around the vee-validate
library. It provides a few things:
- Composable components for building forms.
- A
<FormField />
component for building controlled form fields. - Form validation using
zod
. - Applies the correct
aria
attributes to form fields based on states, handle unqiue IDs - Built to work with all Radix Vue components.
- Bring your own schema library. We use
zod
but you can use any other supported schema validation you want, likeyup
orvalibot
. - You have full control over the markup and styling.
vee-validate makes use of two flavors to add validation to your forms.
- Composition API
- Higher-order components (HOC)
Anatomy
<template>
<form>
<Field v-slot="{ ... }">
<FormItem>
<template #label>
<FormLabel />
</template>
<FormControl>
<!-- any Form Input component or native input elements -->
</FormControl>
<template #description>
<FormDescription />
</template>
<template #message>
<FormMessage />
</template>
</FormItem>
</Field>
</form>
</template>
The <Field/>
component is auto-imported by the @vee-validate/nuxt
module. You can change the name of the impported components in your nuxt.config .ts
file. You can visit here for more information.
Source code
Click here to see the source code for this component on GitHub. Feel free to copy it and adjust it for your own use.
Installation
npx ui-thing@latest add form