The easiest way to add native form validation in Vue.js. ✔
Tags: vue, webdev, javascript, tutorial
Published: 2020-08-14 14:17:56

Now, this statement might be bold but this is what I found out to be the easiest way possible to add some validations _natively_. Though there are many libraries like [FormValidation](https://formvalidation.io/guide/examples/integrating-with-vue/) and [Vuelidate](https://vuelidate.js.org/), one of the simpler way to check the input elements (and others) is to go the native way which is built into Vue.

Ready to add some checks? Let's get this real quick!

![Valid GIF](https://media.giphy.com/media/h4ZdelsbEnuRzsmG2Z/giphy.gif)
<figcaption>It doesn't matter if the form is valid or not, what matters is that you're valid! (I made a bad sentence 🤦‍♂️)</figcaption>
---

## What's in the form? 📄

Let's take the simplest of the lot. There are two input fields, one drop-down and one submit button. It doesn't look pretty, and remember, we're here to do the validation.

Here are the different states of our form:

#### The default state

![Default state form](https://dev-to-uploads.s3.amazonaws.com/i/xltwdr91tn5arm8yf5ca.jpg)

#### The filled state

![Filled State form](https://dev-to-uploads.s3.amazonaws.com/i/4irgqsckkkyyd78exsx6.jpg)

#### The error(s) state

If one of the required fields is not filled...

![First error state](https://dev-to-uploads.s3.amazonaws.com/i/4rtzqwo1cgfjwi3p4rup.jpg)

If you try to submit without your name/review/ratings...

![Second error state](https://dev-to-uploads.s3.amazonaws.com/i/x62lnpnczu2hja1v36h4.jpg)

---

## Code it! 👨‍💻

I hope you're good with the HTML and CSS part of the form. If not, you can see the code in the embed towards the end of this article.

The `product-review` component takes in the following HTML as a [`template`](https://vuejs.org/v2/guide/components.html#Base-Example):

```html
<form class="form" @submit.prevent="onSubmit">
        <p>
          <label for="name">Name:</label>
          <input id="name" v-model="name">
        </p>
        
        <p>
          <label for="review">Review:</label>      
          <textarea id="review" v-model="review"></textarea>
        </p>
        
        <p>
          <label for="rating">Rating:</label>
          <select id="rating" v-model.number="rating">
            <option>⭐⭐⭐⭐⭐</option>
            <option>⭐⭐⭐⭐</option>
            <option>⭐⭐⭐</option>
            <option>⭐⭐</option>
            <option>⭐</option>
          </select>
        </p> 
        <p>
          <input type="submit" value="Submit"> 
        </p>    
    </form>
```
As you can see, it's a pretty straightforward code having the `@submit.prevent` [event modifier](https://vuejs.org/v2/guide/events.html#Event-Modifiers) attached to the `onSubmit` method which we will define later.

We're using the [`v-model`](https://vuejs.org/v2/api/#v-model) directive on the `name` input, `review` text field, and the `rating` selector to give us [two-way data-binding](https://vuejs.org/v2/guide/forms.html).

### Add custom validation

Let's first create the `onSubmit` method. Here, we make the `productReview` object which refers to the `name`, `review` and `rating` which should've been initialised inside the [`data()`](https://vuejs.org/v2/api/#data) object as `null`.

```js
onSubmit() {
    let productReview = {
        name: this.name,
        review: this.review,
        rating: this.rating
    }
    this.name = null
    this.review = null
    this.rating = null
}
```
To collect the errors, we'll make an empty `errors` array in our data object of [Vue instance](https://vuejs.org/v2/guide/instance.html).

Next, we use good old `if-else` in JavaScript to check if there is some data entered in these three fields or not. Hence, we wrap our `productReview` object inside the `if` as:

```js
if(this.name && this.review && this.rating) {
    let productReview = {
        name: this.name,
        review: this.review,
        rating: this.rating
    }
    this.name = null
    this.review = null
    this.rating = null
}
``` 
Now, if these values are not filled in, we add the `else` block and check if there is not a `name`, `rating` or a `review`, then simply [`push()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) this into our initially empty `errors` array with the error message we want to display inside the `push()` function's argument as a String.

```js
else {
    if(!this.name) this.errors.push("Name required.")
    if(!this.review) this.errors.push("Review required.")
    if(!this.rating) this.errors.push("Rating required.")
}
```

### Display those errors

Inside of our template, we add a new `<p>` tag before the name input field. Using Vue's [`v-if`](https://vuejs.org/v2/api/#v-if) directive, we'll check if errors array has some [`length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length). This means when `errors` is _not_ empty (i.e it has some errors), we add a `<b>` which says "Please correct the following error(s):"

```html
<p v-if="errors.length">
    <b>Please correct the following error(s):</b>
    <ul>
        <li v-for="error in errors">{{ error }}</li>
    </ul>
</p>
```
For a single of multiple errors, we'll display it in an unordered list. Therefore, for each `<li>`, we use the [`v-for`](https://vuejs.org/v2/api/#v-for) directive to iterate through the array to print each of the `error`. 

And there you have it! Try submitting the form by leaving on or two (or if you don't even have a name, leave them all! （￣︶￣）↗). The form should send the error message(s). 🥳

If you're stuck somewhere in the code or just want to see the output, I've embedded the Pen below:

{% codepen https://codepen.io/kvaibhav01/pen/MWyaMro default-tab=result %}

---

## Where to next? 🤔

While this was a super simple beginner-friendly approach towards form validation in Vue, your app may be much more complex or big. For that you can try out the following resources:

- Vue.js official [Cookbook example](https://vuejs.org/v2/cookbook/form-validation.html).
- [Validation with VeeValidate](https://www.digitalocean.com/community/tutorials/template-driven-form-validation-in-vuejs).
- [Vuelidate examples](https://vuelidate.js.org/#examples).

---

_Thanks for reading, I appreciate it! Have a good day. (✿◕‿◕✿)_

---
<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="en" dir="ltr">🥵🥶🥵🥶<br><br>If you&#39;re unsure what a bool is, this will explain: <a href="https://t.co/4hjKJtxYNE">https://t.co/4hjKJtxYNE</a><br><br>Image source: <a href="https://t.co/2mBLe57X92">https://t.co/2mBLe57X92</a><a href="https://twitter.com/hashtag/DevHumour?src=hash&amp;ref_src=twsrc%5Etfw">#DevHumour</a> <a href="https://twitter.com/hashtag/Programming?src=hash&amp;ref_src=twsrc%5Etfw">#Programming</a> <a href="https://t.co/WVoBkIxLtT">pic.twitter.com/WVoBkIxLtT</a></p>&mdash; Microsoft Developer UK (@msdevUK) <a href="https://twitter.com/msdevUK/status/1293088520425406465?ref_src=twsrc%5Etfw">August 11, 2020</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
---

#### [📫 Subscribe to my weekly developer newsletter 📫](https://mailchi.mp/f59beeac6b9b/devupdates)

##### PS: From this year, I've decided to write here on DEV Community. Previously, I wrote on Medium. If anyone wants to take a look at my articles, [here](https://medium.com/@vaibhavkhulbe)'s my Medium profile.