Validating input fields is imperative when crafting forms to collect data from your customers. Form validation gives you total control of the customer experience and enables you to guide the user through the path you want them to take.
You should conduct validation on both the client and server side of your application for quality assurance. In this tutorial, we’ll walk through how to conduct simple form validation in Vue.js.
You can create forms in Vue applications just as you would with HTML5. That means little to no additional skills are required to build forms in the Vue template section of any component with plain HTML.
This tutorial is suited for developers at all stages, including beginners. Below are a few things you should already have before going through this tutorial.
node -v
npm uninstall -g vue-cli
npm install -g @vue/cli
npm install
Vuelidate is a simple, lightweight, model-based validation library for Vue applications. Validation rules are added to a validation object where a given component is defined (instead of directly inside the DOM).
Vuelidate works well with other libraries such as Moment and VueX and can be added with the add
command on the Vue CLI. It also has support for collection validation, nested models, and function composition.
Create a new Vue application in your terminal.
Vue create newapp
Choose the default setup. After the project has been created, navigate to the new project folder.
cd newapp
Install Vuelidate with your package manager of choice. I use npm, so I did:
npm add vuelidate
This installs the library for your newapp
project. The next step is to register it as a plugin so you can use it in your Vue app.
Go to the main.js
file inside the src
directory and register it. Your main.js
file should look like this:
import Vue from 'vue' import App from './App.vue' import Vuelidate from "vuelidate"; Vue.use(Vuelidate); Vue.config.productionTip = false new Vue({ render: h => h(App), }).$mount('#app')
Vue also ships with a graphical user interface that you can use to manage Vue.js applications. To access it, go to your terminal and run the following command.
vue ui
This will lead you to a browser interface that looks like this:
You can create a new Vue project with this GUI or import one. Since we already created the newapp
project, let’s import it. Click “Import” to open your file manager and find your newapp
folder. The project is popped into the GUI.
The GUI dashboard has five tabs. The third tab, labeled “Project dependencies,” is where you can find Vuelidate (which we added earlier).
You can add or remove dependencies straight from the GUI dashboard. To run the application, use the fifth tab (“Project tasks”). Select the “serve” task and hit “Run task” to see your application served in localhost.
Now that we’ve brought in the Vuelidate library and registered it as a plugin, let’s build out a simple form to see it in action. Open the app.vue
file and replace the content with the code block below.
<template> <div id="visa"> <h1>Create a New Vue Account</h1> <form> <label for="full name">Full Name:</label> <input type="text"> <br> <label for="email">Email Address:</label> <input type="text"> <br> <span></span> <label for="password">Password:</label> <input type="text"><br> <span></span> <br> <label for="age">Age:</label> <input type="text"> </form> </div> </template> <script> export default { name: 'app' } </script>
This displays a simple contact form that looks like this:
To set validation rules for the number of characters, you need to be present in the name and password fields. The validations option is available to you once Vuelidate is registered as a plugin.
In the script section of your app.vue
file, add the code block below.
<script> import { required, minLength, between } from 'vuelidate/lib/validators' export default { name: 'app', data() { return { name: '', password: '', age: '' } }, validations: { name: { required, minLength: minLength(4) }, password: { required, minLength: minLength(4) }, age: { required, between: between(18,45) } } } </script>
First, we imported the following built-in validators.
minLength
, which refers to the minimum number of characters for a given required input fieldrequired
, which points to a required input field that has to be filled before submission is possiblebetween
, which points to a range of numbers for input to be given inIn the template section of your app.vue
file, replace the current content with the following block of code.
<template> <div id="visa"> <h1>Create a New Vue Account</h1> <form> <div> <!-- Full name validation --> <div class="form-group" :class="{ 'form-group--error': $v.name.$error }"> <label class="form__label">Full Name</label> <input class="form__input" v-model.trim="$v.name.$model"/> </div> <span class="error" v-if="!$v.name.required">Field is required</span> <span class="error" v-if="!$v.name.minLength">Name must have at least {{$v.name.$params.minLength.min}} letters.</span> <tree-view :data="$v.name" :options="{rootObjectKey: '$v.name', maxDepth: 2}"></tree-view> <!-- Email Address--> <label for="email">Email Address</label> <input type="text"> <br> <span></span> <!-- Password validation--> <div class="form-group" :class="{ 'form-group--error': $v.password.$error }"> <label class="form__label">Password</label> <input class="form__input" v-model.trim="$v.password.$model"/> </div> <span class="error" v-if="!$v.password.required">Field is required</span> <span class="error" v-if="!$v.password.minLength">Name must have at least {{$v.password.$params.minLength.min}} letters.</span> <tree-view :data="$v.password" :options="{rootObjectKey: '$v.password', maxDepth: 2}"></tree-view> <!-- Age validation--> <div class="form-group" :class="{ 'form-group--error': $v.age.$error }"> <label class="form__label">Age</label> <input class="form__input" v-model.trim="$v.age.$model"/> </div> <span class="error" v-if="!$v.age.between">Must be between {{$v.age.$params.between.min}} and {{$v.age.$params.between.max}}</span> <tree-view :data="$v.age" :options="{rootObjectKey: '$v.age', maxDepth: 2}"></tree-view> </div> </form> </div> </template>
For every option, we used the v-model
directive to bind the input data and also specify in spans the rules and how they are flagged. The $v
selector, which is now available for use since Vuelidate has been added, makes it easy to build logic around the model.
The form looks exactly as it did before except that it can now show validators, according to the rules we set.
That’s how easy it is to use the Vuelidate library to handle validations with the v-model
directive. The full code for this project is available on GitHub.
In this tutorial, we went over how to handle basic form input validation with the Vuelidate library. We also showed how to use the Vue GUI and ran through a quick overview of how it works.
In future posts, we’ll dive deeper into Vuelidate and explore how we can use it to handle submission and passwords.
Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens in your Vue apps, including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.
The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error and what state the application was in when an issue occurred.
Modernize how you debug your Vue apps — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowHandle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.
Design React Native UIs that look great on any device by using adaptive layouts, responsive scaling, and platform-specific tools.
Angular’s two-way data binding has evolved with signals, offering improved performance, simpler syntax, and better type inference.