DEV Community

loading...
Cover image for Using Vue3 And Vuelidate for Forms and Form Validation

Using Vue3 And Vuelidate for Forms and Form Validation

Aaron K Saunders
See more, like and subscribe 👉🏾 ‪Aaron Saunders 📺 https://www.youtube.com/aaronsaundersci?sub_confirmation=1
Updated on ・4 min read

See My Upcoming Book On Ionic & Vue JS


So last week I did a short video about using Vee-Validate with Vue3 and Ionic Framework new Vue Components.
I had someone ask me why didn't I used Vuelidate? There was no specific reason other than the last time I needed form validation, I had used Vee-Validate.

So what I have done here is reproduce the same example from the previous form/form validation post but this time using Vuelidate.

Code available at end of the post and please check out my videos on Vue3 and Ionic Framework

Setting Up

We are assuming you already have a vue3 project.

Install the library

npm install @vuelidate/core@2.0.0-alpha.4
npm install @vuelidate/validators@2.0.0-alpha.2
Enter fullscreen mode Exit fullscreen mode

Since I am using typescript, I needed to make this change in shims-vue.d.ts

declare module '@vuelidate/core';
declare module '@vuelidate/validators';
Enter fullscreen mode Exit fullscreen mode

Setting up My Form Fields

First in the script area of my component, import the library

import { useVuelidate } from "@vuelidate/core";
import { required, email } from "@vuelidate/validators";
Enter fullscreen mode Exit fullscreen mode

In the setup function lets defined the form fields.

// set fields and some initial values
const fform = reactive({
  title: "",
  body: "",
  emailAddress: "",
  gender: "MALE",
  save: true,
});
Enter fullscreen mode Exit fullscreen mode

Next we will map the rules to the fields using rules from vuelidate that we imported.

const rules = {
  title: { required },
  body: { required },
  emailAddress: { required, email },
  gender: {},
  save: {},
};
Enter fullscreen mode Exit fullscreen mode

We bind all of this to the Vuelidate object using the useVuelidate hook. I could have used ref originally to avoid all of this, but I like working with a form object and not a bunch of fields.

Ref & Reactive:

  • ref() takes a primitive value and returns a reactive and mutable ref object
  • reactive() takes an object and returns a reactive proxy of the original
const vv = useVuelidate(rules, {
  title: toRef(fform, "title"),
  body: toRef(fform, "body"),
  emailAddress: toRef(fform, "emailAddress"),
  gender: toRef(fform, "gender"),
  save: toRef(fform, "save"),
});
Enter fullscreen mode Exit fullscreen mode

We need to have a function to handle when the user submits the form. In this situation we first trigger a validation of the form using vv.value.$touch(); if there is an error, we exit and do not submit the form.

// handle the submit of the form, only called
// if the form is valid
const onSubmit = () => {
  vv.value.$touch();

  if (vv.value.$invalid) return;

  alert("Form Submitted " + JSON.stringify(fform, null, 2));
};
Enter fullscreen mode Exit fullscreen mode

Since we are using a setup method, we need to return the appropriate functions and properties so they can be accessible in the template.

return {
  router: useRouter(),
  onSubmit,
  vv,
};
Enter fullscreen mode Exit fullscreen mode

Setting up My Form Template

In my form I have a few fields and since I am using Ionic components, initially I was concerned I would have to do some extra work but i didn't have to.

We have access to the model associated with the fields we created by using the vv object returned from the useVuelidate call; We use those models in our form

<ion-item>
  <ion-label>Title</ion-label>
  <ion-input type="text" name="title" v-model="vv.title.$model" />
</ion-item>
Enter fullscreen mode Exit fullscreen mode

Form Initial Values

The great thing is since we are working with vue binding, the initial values that we set for our form fields get passed in through the model are set the input elements

<ion-item>
  <ion-label>Gender</ion-label>
  <ion-select name="gender" v-model="vv.gender.$model">
    <ion-select-option>MALE</ion-select-option>
    <ion-select-option>FEMALE</ion-select-option>
  </ion-select>
</ion-item>
Enter fullscreen mode Exit fullscreen mode

Alt Text

See above where we setup form object

Form Submit

No special magic with submitting the form, we just call our function and check for errors. If errors we can render them

<form @submit.prevent="onSubmit" novalidate>
 ...
</form>
Enter fullscreen mode Exit fullscreen mode

Form Field Errors

Form fields have error objects associated with them, we can access the errors using the name of the field and the vuelidate object.
The code below renders the first error message associated with the input element named title

<p>{{ vv?.title?.$errors[0]?.$message }}</p>
Enter fullscreen mode Exit fullscreen mode

Wrap Up

This was just a quick look at Vuelidate, I will be taking a deeper dive using the form and form validation functionality with a Modal Form video, blog post I am working on. In that example we will be using nested objects and more complex UI so it should be interesting to see how it works out.

Source Code

GitHub logo aaronksaunders / ionic-vue-validation-app

Sample app showing vue3 and ionic form validation examples with

Ionic Vue Videos

Alt Text
Click To View Playlist

Discussion (2)

Collapse
gyurmatag profile image
Varga György Márk

Hi!
Nice tutorial! I have one question though. The form is valid on initial load even when using required on inputs (the form's $invalid attribure is false) and the form is not touched. How could we fix this?

Collapse
gyurmatag profile image
Varga György Márk

github.com/vuelidate/vuelidate/iss...
I found that it might be a bug in the library...