DEV Community

Maxwell Adapoe
Maxwell Adapoe

Posted on • Updated on

Building a Form in Vue using Tailwind CSS and VeeValidate (Part 2)

This is part 2 of 2 on how to create a simple login form with validation using Vue.js, Tailwind CSS and VeeValidate for validation.

You can clone the example app from my repo on Github.

Link to Part 1 here

Part 2: Creating our form and adding validation

In this Part we will look at creating our form and hooking up Veevalidate for frontend form validation

Creating the form

Create a new vue component Login.vue in your src/views folder. You can use the command below

touch src/views/Login.vue
Enter fullscreen mode Exit fullscreen mode

paste the below code into the file:

<template>
  <div class="flex justify-center items-center mt-52">
    <div class="w-full max-w-xs">
      <form class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
        <div class="identity-input mb-4">
          <label
            for="identity"
            class="block text-gray-700 text-sm font-bold mb-2"
          >
            Email</label
          >
          <input
            id="identity"
            class="shadow appearance-none borderrounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline"
            type="text"
            placeholder="Email"
            aria-describedby="emailHelp"
            v-model="email"
          />
          <span class="text-xs text-red-700" id="emailHelp"></span>
        </div>

        <div class="password-input mb-6">
          <label
            for="identity"
            class="block text-gray-700 text-sm font-bold mb-2"
            >Password</label
          >

          <input
            aria-describedby="passwordHelp"
            v-model="password"

            class="shadow appearance-none borderrounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline"
            id="password"
            type="password"
            placeholder="*******"
          />

          <span class="text-xs text-red-700" id="passwordHelp"></span>
        </div>

        <div class="flex items-center justify-between">
          <button
            class="bg-blue-600 hover:bg-black text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
            type="submit"
          >
            Sign In
          </button>
          <a
            class="inline-block align-baseline font-bold text-sm text-blue-500 hover:text-blue-800"
            href="#"
          >
            Forgot Password?
          </a>
        </div>
      </form>
    </div>
  </div>
</template>

<script>
export default {
  name: "Login",
  data() {
    return {
      email: "",
      password: "",
    };
  },
  methods: {
    login() {
      console.log("logging in");
    },
  },
};
</script>

Enter fullscreen mode Exit fullscreen mode

Setting up the Login Route

in your routes/index.js file add the below


...
import Login from '../views/Login.vue'

...

const routes = [
...,
  {
    path: '/login',
    name: 'Login',
    component: Login
  },
]
...
Enter fullscreen mode Exit fullscreen mode

in your App.vue file add

...
   <router-link
            to="/link"
            class="block ml-4 mt-4
            lg:inline-block lg:mt-0 text-blue-200
            hover:text-white"
            >Login</router-link>

...
Enter fullscreen mode Exit fullscreen mode

With this in place navigating to http://localhost:8080/#/login should look like this :

Alt Text

Setting up VeeValidate

To add validation we need to install VeeValidate

npm install vee-validate --save

Enter fullscreen mode Exit fullscreen mode

Once installation is complete in your main.js add

...
import {extend,ValidationObserver, ValidationProvider} from 'vee-validate';
import * as rules from 'vee-validate/dist/rules';


Vue.component('ValidationObserver', ValidationObserver);
Vue.component('ValidationProvider', ValidationProvider);

Object.keys(rules).forEach(rule => {
  extend(rule, rules[rule]);
});
...
Enter fullscreen mode Exit fullscreen mode

extend Allows you to add more rules to be used globally by the vee-validate functions and components.

ValidationObserver is a component that wraps your forms and provides aggregated validation state for all the fields nested under it.

ValidationProvider component is a component that wraps your inputs and provides validation states.

We then import all the the default rules using import * as rules from 'vee-validate/dist/rules'; and iterate over them using the Object.keys(rules).forEach function.

With that in place we can move on to making the magic Happen.

Adding Validation to the form.

We now need to wrap our form component with the ValidationObserver component

...
 <ValidationObserver ref="loginForm">
<form >
...
</form>
</ValidationObserver>
...
Enter fullscreen mode Exit fullscreen mode

The Validation Provider now goes around our inputs. It accepts a v-slot="v" attribute. To make things a little less verbose we can use ES6's object destructing and replace it with v-slot="{ errors }".
It also accepts a name attribute which is used in displaying the error messages and also accepts the validation rules.
Read more about registering the Validation Provider heere
With this in place we can now make use of the errors and display them in our html as well

      <ValidationProvider name="Email" rules="required|email" v-slot="{ errors }">
            <div class="email-input mb-4">
              <label
                for="email"
                class="block text-gray-700 text-sm font-bold mb-2"
              >
                Email</label
              >
              <input
                id="email"
                class="shadow appearance-none borderrounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline"
                type="text"
                placeholder="Email"
                aria-describedby="emailHelp"
                v-model="email"
              />

              <span class="text-xs text-red-700" id="emailHelp">{{
                errors[0]
              }}</span>
            </div>
          </ValidationProvider>

          <ValidationProvider
            name="Password"
            rules="required|min:6"
            v-slot="{ errors }"
          >
            <div class="password-input mb-6">
              <label
                for="password"
                class="block text-gray-700 text-sm font-bold mb-2"
                >Password</label
              >

              <input
                aria-describedby="passwordHelp"
                v-model="password"
                class="shadow appearance-none borderrounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline"
                id="password"
                type="password"
                placeholder="*******"
              />

              <span class="text-xs text-red-700" id="emailHelp">{{
                errors[0]
              }}</span>
              <span class="text-xs text-red-700" id="passwordHelp"></span>
            </div>
          </ValidationProvider>
Enter fullscreen mode Exit fullscreen mode

Finally we need to ensure that the Validation Observer is triggered when the submit button is pressed to ensure that validation has been passed successfully.
We need to add a v-slot="{ handleSubmit }" to our Validation Observer and also add an @submit.prevent event listener to our form

...
 <ValidationObserver v-slot="{ handleSubmit }" ref="loginForm">
                    <form @submit.prevent="handleSubmit(login)" class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
...
Enter fullscreen mode Exit fullscreen mode

That sums it up. Your page should look like this once you click the submit button without entering any values or when you enter an invalid value for your email / password

Alt Text

Top comments (0)