How To Do Form Validation in Vue with Tanstack Form
Overview This blog post show you a simple example of how to quickly integrate form validation in your vuejs or nuxt js application using Tanstack Form. Here is a full video with a more complex example for you to review if you want to dive deeper Let's Get Started npm create vite@latest my-vue-app --template vue-ts cd my-vue-app install tanstack form npm install @tanstack/vue-form create a file SimpleForm.vue and lets create the form instance interface Thought { title: string; note: number; } const form = useForm({ onSubmit: async ({ value }) => { // Display form data on success alert(JSON.stringify(value)); }, defaultValues: { note: '', title: '', }, }); add this as the template since this is the normal way to implement a form with v-model for capturing the values from user input Add New Thought Title: Note: Add Friend Now lets add the Tanstack Form code, Add new thought Title: Note: Add Friend notice how we have wrapped the input element for the form.Field element, using the slot to pass information on the field and capturing input events for when user enters the value. at this point the values from the form are accessible from the form object we created in the script section of the application. const { title, note } = form.state.values; but we are using this tool because we want to have a structured way of validating the form. add the following to the template, wrap the fieldset in a form ... update script section, to call the form.handleSubmit when user clicks the submit button in the form const handleSubmit = () => { form.handleSubmit(); }; Now lets add a simple validator to make sure the fields are not empty on the title on the note update the form instance code to display alert on success const form = useForm({ onSubmit: async ({ value }) => { // Do something with form data alert(JSON.stringify(value)); }, defaultValues: { note: '', title: '', }, }) update template to display message when there is an error Title: {{ field.state.meta.errors?.length && field.state.meta.isTouched ? field.state.meta.errors[0] : null }} Note: {{ field.state.meta.errors?.length && field.state.meta.isTouched ? field.state.meta.errors[0] : null }} So now u should get error message if attempting to submit with empty fields, but we would like to disable the submit button if the form is not valid at all. to do this we need to validate the form onMount and subscribe to form changes to update the submit button user interface. But first lets update our error message so it is only displayed if the fields has been touched. {{ field.state.meta.errors?.length && field.state.meta.isTouched ? field.state.meta.errors[0] : null }} now lets validate onMount also finally lets update the code on the submit button {{ isSubmitting ? '...' : 'Add Thought' }} Simple Example in Stackblitz Full Project w/ Source Code This was a quick run through of a simple example. I have a more complex example here Tanstack Form with Zod Validation
Overview
This blog post show you a simple example of how to quickly integrate form validation in your vuejs or nuxt js application using Tanstack Form.
Here is a full video with a more complex example for you to review if you want to dive deeper
Let's Get Started
npm create vite@latest my-vue-app --template vue-ts
cd my-vue-app
install tanstack form
npm install @tanstack/vue-form
create a file SimpleForm.vue
and lets create the form instance
interface Thought {
title: string;
note: number;
}
const form = useForm<Thought>({
onSubmit: async ({ value }) => {
// Display form data on success
alert(JSON.stringify(value));
},
defaultValues: {
note: '',
title: '',
},
});
add this as the template since this is the normal way to implement a form with v-model for capturing the values from user input
<template>
/>
Note:
v-model="thought.note" type="text" />
/>
template>
Now lets add the Tanstack Form code,
<template>
name="title">
v-slot="{ field }">
template>
/>
name="note">
<template v-slot="{ field }">
template>
/>
notice how we have wrapped the input
element for the form.Field
element, using the slot to pass information on the field and capturing input events for when user enters the value.
at this point the values from the form are accessible from the form
object we created in the script section of the application.
const { title, note } = form.state.values;
but we are using this tool because we want to have a structured way of validating the form.
add the following to the template, wrap the fieldset in a form
update script section, to call the form.handleSubmit
when user clicks the submit button in the form
const handleSubmit = () => {
form.handleSubmit();
};
Now lets add a simple validator to make sure the fields are not empty
on the title
name="title"
:validators="{
onChange: ({ value }) => {
if (!value || value === '') {
return 'this is a required value';
}
},
}"
>
on the note
name="note"
:validators="{
onChange: ({ value }) => {
if (!value || value === '') {
return 'this is a required value';
}
},
}"
>
update the form
instance code to display alert on success
const form = useForm<Thought>({
onSubmit: async ({ value }) => {
// Do something with form data
alert(JSON.stringify(value));
},
defaultValues: {
note: '',
title: '',
},
})
update template to display message when there is an error
name="title"
:validators="{
onChange: ({ value }) => {
if (!value || value === '') {
return 'this is a required value';
}
},
}"
>
<template v-slot="{ field }">
{{
field.state.meta.errors?.length &&
field.state.meta.isTouched
? field.state.meta.errors[0]
: null
}}
template>
/>
name="note"
:validators="{
onChange: ({ value }) => {
if (!value || value === '') {
return 'this is a required value';
}
},
}"
>
<template v-slot="{ field }">
{{
field.state.meta.errors?.length &&
field.state.meta.isTouched
? field.state.meta.errors[0]
: null
}}
template>
So now u should get error message if attempting to submit with empty fields, but we would like to disable the submit button if the form is not valid at all.
to do this we need to validate the form onMount
and subscribe to form changes to update the submit button user interface.
But first lets update our error message so it is only displayed if the fields has been touched.
{{
field.state.meta.errors?.length &&
field.state.meta.isTouched
? field.state.meta.errors[0]
: null
}}
now lets validate onMount
also
name="note"
:validators="{
onChange: ({ value }) => {
if (!value || value === '') {
return 'this is a required value';
}
},
onMount: ({ value }) => {
if (!value || value === '') {
return 'this is a required value';
}
},
}"
>
finally lets update the code on the submit button
<template v-slot="{ canSubmit, isSubmitting }">
template>
Simple Example in Stackblitz
Full Project w/ Source Code
This was a quick run through of a simple example. I have a more complex example here Tanstack Form with Zod Validation