Vue 2 Form Validation + Submit Form Data with Axios Tutorial

Vue JS Form Validation Tutorial; Form validation is a significant part of web application development, and it protects from malicious users, security vulnerabilities, and web form abuse.

This tutorial will teach you how to implement form validation in the Vue js application using the Vuelidate package.

We will create a basic form with name, email, phone, password fields; we will implement required password confirmation, valid email type, and minimum and maximum characters validation.

Apart from validating a form, we will also describe how eloquently handle form data with Axios HTTP client; here are the key points we address in this vue form validation example.

  • Create a simple contact form
  • Design form using bootstrap
  • Integrate form validation using v-model
  • Create fake REST API to store form object or data
  • Submit form data to the server using event handler and Axios

Vue JS Client-Side Form Validation Example

  • Step 1: Set Up Vue CLI Tool
  • Step 2: Install Vue Project
  • Step 3: Add Axios and Bootstrap Packages
  • Step 4: Install Vuelidate Library
  • Step 5: Register Packages in Vue
  • Step 6: Create Contact Form Component
  • Step 7: Create JSON Server
  • Step 8: Handle Form Validation in Vue JS
  • Step 9: Start Vue Application

Set Up Vue CLI Tool

Entire Vue development starts with VUE CLI; let us install this prodigy.

npm install -g @vue/cli

# or

yarn global add @vue/cli

Vue Gatsby Error

Node.js Gatsby error – “digital envelope routines::unsupported …”

Error: digital envelope routines::unsupported

opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'

To remove above error for invoking the app, make sure to update the "scripts": [] array in package.json file.

"scripts": {
    "serve": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
    "build": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
    "lint": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service lint"
},

Fix Multi Word Error

In order to fix multi-word error, insert the given code in vue.config.js file.

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false,
})

Install Vue Project

After setting up the VUE command-line interface tool, install the latest version of the vue js app.

vue create vue-demo-app

Move into the project folder.

cd vue-demo-app

Add Axios and Bootstrap Packages

In this section, we have to recklessly accomplish two tasks, adding the Axios package and Bootstrap CSS framework. Make sure to execute both the provided commands respectively.

npm install vue-axios axios
npm install bootstrap

Install Vuelidate Library

Install the Vuelidate plugin, it lets you integrate the form validation in vue. This plugin is a gold mine of features for form validation; run command to add the plugin into the project.

npm install vuelidate

Register Packages in Vue

Open src/main.vue file; now in this file we have to register all the packages to create user registration form in vue.

import Vue from 'vue'
import App from './App.vue'

import 'bootstrap/dist/css/bootstrap.min.css';

import VueAxios from 'vue-axios'
import axios from 'axios'
import Vuelidate from 'vuelidate'

Vue.use(VueAxios, axios)
Vue.use(Vuelidate)


new Vue({
  render: h => h(App)
}).$mount('#app')

Create Contact Form Component

Create the reusable form file, formulate components/UserForm.vue, then add the following code within the file.

<template>
    
</template>

<script>

export default {
    data() {
        return {
            
        }
    },
    mounted() {

    }
 
}
</script>

Further, register the UserForm component in the src/App.vue file.

<template>
  <div class="container mt-5 text-center">
    <UserForm />
  </div>
</template>

<script>
    import UserForm from './components/UserForm.vue'

    export default {
      name: 'App',
      components: {
        UserForm
      }
    }
</script>

Create Fake REST API with JSON Server

Not just validation, but this agile tutorial will show you a drastically easy method for creating a fake REST API, and we will use this API to submit the form data to the server.

Now, install the JSON server package.

npm install json-server

Subsequently, create backend folder in the root of your project, also create db.json file within the directory.

Insert the given code in the backend/db.json file.

{
  "contacts": [

  ]
}

Next, invoke the JSON server, and your API is ready to be served.

json-server --watch backend/db.json --port 8888

Create Vue Form + Add Form Validation + Submit Form

In this section, we have to create the form using the Bootstrap UI, add validation using the vuelidate and v-model directive. And use REST API to submit the form data after clearing the form validation onto the server.

Update code in src/components/UserForm.vue file.

<template>
    <div class="container">

        <h2 class="mt-5 mb-5 text-center">Vue Client Side Form Validation Example</h2>

        <form @submit.prevent="onFormSubmit">
            <div class="form-group">
                <label>Name</label>
                <input type="text" v-model="contacts.name" id="name" name="name" class="form-control"
                    :class="{ 'is-invalid': isValid && $v.contacts.name.$error }" />
                
                <div v-if="isValid && !$v.contacts.name.required" class="invalid-feedback">Name is required</div>
            </div>

            <div class="form-group">
                <label>Email</label>
                <input type="email" v-model="contacts.email" id="email" name="email" class="form-control"
                    :class="{ 'is-invalid': isValid && $v.contacts.email.$error }" />
                
                <div v-if="isValid && $v.contacts.email.$error" class="invalid-feedback">
                    <span v-if="!$v.contacts.email.required">Email is required</span>
                    <span v-if="!$v.contacts.email.email">Email is not valid</span>
                </div>
            </div>

           <div class="form-group">
                <label>Phone</label>
                <input type="text" v-model="contacts.phone" id="phone" name="phone" class="form-control"
                    :class="{ 'is-invalid': isValid && $v.contacts.phone.$error }" />
                
                <div v-if="isValid && $v.contacts.phone.$error" class="invalid-feedback">
                    <span v-if="!$v.contacts.phone.required">Phone number is required</span>
                </div>
            </div>

             <div class="form-group">
                <label>Gender</label>
                <div class="form-group" :class="{ 'is-invalid': isValid && $v.contacts.gender.$error }">
                    <div class="form-check form-check-inline" :class="{ 'is-invalid': isValid && $v.contacts.gender.$error }">
                        <input class="form-check-input" type="radio" name="gender" v-model="contacts.gender" id="gender1" value="male">
                        <label class="form-check-label" for="gender1">Male</label>
                    </div>
                    <div class="form-check form-check-inline" :class="{ 'is-invalid': isValid && $v.contacts.gender.$error }">
                        <input class="form-check-input" type="radio" name="gender" v-model="contacts.gender" id="gender2" value="female">
                        <label class="form-check-label" for="gender2">Female</label>
                    </div>

                    <div v-if="isValid && $v.contacts.gender.$error" class="invalid-feedback">
                        <span v-if="!$v.contacts.gender.required">This field is required</span>
                    </div>                    
                </div>
            </div>

            <div class="form-group">
                <label>Password</label>
                <input type="password" v-model="contacts.password" id="password" name="password" class="form-control"
                    :class="{ 'is-invalid': isValid && $v.contacts.password.$error }" />
                <div v-if="isValid && $v.contacts.password.$error" class="invalid-feedback">
                    <span v-if="!$v.contacts.password.required">Password field is required</span>
                    <span v-if="!$v.contacts.password.minLength">Maxium 6 characters allowed</span>
                </div>
            </div>

            <div class="form-group">
                <label>Confirm Password</label>
                <input type="password" v-model="contacts.confirmPassword" id="confirmPassword" name="confirmPassword"
                    class="form-control" :class="{ 'is-invalid': isValid && $v.contacts.confirmPassword.$error }" />
                <div v-if="isValid && $v.contacts.confirmPassword.$error" class="invalid-feedback">
                    <span v-if="!$v.contacts.confirmPassword.required">Confirm Password field is required</span>
                    <span v-else-if="!$v.contacts.confirmPassword.sameAsPassword">Passwords should be matched</span>
                </div>
            </div>

            <div class="form-group">
                <button class="btn btn-primary btn-block">Submit</button>
            </div>
        </form>
        
    </div>
</template>

<script>
    import { required, email, sameAs, minLength } from "vuelidate/lib/validators";

    export default {
        data() {
            return {
                contacts: {
                    name: "",
                    email: "",
                    phone: "",
                    gender: "",
                    password: "",
                    confirmPassword: ""
                },
                isValid: false
            };
        },
        validations: {
            contacts: {
                name: {
                    required
                },
                email: {
                    required,
                    email
                },
                phone: {
                    required
                },
                gender: {
                    required
                },
                password: {
                    required,
                    minLength: minLength(6)
                },
                confirmPassword: {
                    required,
                    sameAsPassword: sameAs('password')
                }
            }
        },
        methods: {
            onFormSubmit() {              
                this.isValid = true;

                this.$v.$touch();
                if (this.$v.$invalid) {
                    return;
                }

                this.axios.post('http://localhost:8888/contacts', this.contacts).then((response) => {
                    this.resetForm();
                    console.log(response.data);
                })
            }
        },
    };
</script>


<style lang="css">
    .container {
        max-width: 500px !important; 
        text-align: left;
        margin: 0 auto;
    }
    label {
        font-weight: 600;
    }
</style>

Start Vue Application

We are at the last stage of this tutorial, so start the vue app and view it on the browser.

npm run serve
http://localhost:8080

Vue JS Form Validation

Conclusion

Form validation is an imperative technical process that offers pragmatic solutions to amplify the security of the user-provided data. It carefully checks the information entered by the user and lets the site users what they did wrong by showing the alert message.

This vue form registration example told us how to create a form in vue, integrate validation in form, and adequately handle the form data using event handler and submit the form data to the server using Axios HTTP Post request.