VeeValidate

How to use Vue with VeeValidate - free starter

This article will teach you how to use VeeValidate with your MDB project. We are integrating VeeValidate functionality with MDB Vue validation properties for inputs.

Lets see how to use VeeValidate with MDB 5 Vue inputs.

Live preview

Prerequisites

Before starting the project make sure to install the following utilities:


Creating a new project

First, we need to create a new Vite project.

Step 1

Init the project and choose vue framework. You can add a name for your project as we did in example below

        
            
          npm init vite@latest my-vue-app
    
        
    

Step 2

Navigate to app's directory.

        
            
        cd my-vue-app
    
        
    

Step 3

Install dependencies.

        
            
        npm install
    
        
    

Step 4

Setup MDB.

        
            
    npm install mdb-vue-ui-kit
    
        
    

Step 5

Import CSS. Add the following line at the beginning of your main.ts file:

        
            
        import 'mdb-vue-ui-kit/css/mdb.min.css';
    
        
    

Step 6

Import Font Awesome and Roboto font. Add the following lines in public/index.html file inside head section:

        
            
        <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet" />
        <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,900&display=swap" rel="stylesheet" />
    
        
    

Step 7

Enable sourcemaps during development.

        
            
        export default defineConfig({
          plugins: [vue()],
          css: {
            devSourcemap: true,
          },
        });
    
        
    

Step 8

Launch the application.

        
            
        npm run dev
    
        
    

Installation

The next thing we need to do is to install VeeValidate package.

Step 1

Navigate to your project and in your terminal run:

        
            
    npm install vee-validate
    
        
    

Step 2

Clean your project, remove HelloWorld.vue and style.css (don't forget to remove it from main.ts).

Step 3

We will have 8 fields for validation: first name, last name, address, country, email, phone, additional information and confirmation checkbox. Let's prepare a few validation rules that these fields must fulfill. Create validationRules.ts inside src directory and paste the code below.

        
            
    const isRequired = (value: string) => {
      if (value && value.trim()) {
        return true;
      }
    
      return "This is required";
    };
    
    const isLongerThan = (value: string, longerThan: number) => {
      if (value && value.trim().length > longerThan) {
        return true;
      }
    
      return `This needs to be longer than ${longerThan} characters`;
    };
    
    const isValidEmail = (value: string) => {
      if (value && /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}/i.test(value)) {
        return true;
      }
      return "This field must be a valid email";
    };
    
    const isPhoneNumber = (value: string) => {
      if (value && value.length === 9) {
        return true;
      }
      return "Phone number should have exact 9 number";
    };
    
    const isChecked = (value: boolean) => {
      if (value) {
        return true;
      }
    
      return "You need to check this before going any further";
    };
    
    export default {
      name(value: string) {
        return isLongerThan(value, 2);
      },
      lastname(value: string) {
        return isLongerThan(value, 3);
      },
      address(value: string) {
        return isRequired(value);
      },
      country(value: string) {
        return isRequired(value);
      },
      email(value: string) {
        return isValidEmail(value);
      },
      phone(value: string) {
        return isPhoneNumber(value);
      },
      info(value: string) {
        return isLongerThan(value, 10);
      },
      checkbox(value: boolean) {
        return isChecked(value);
      },
    };
    
    
        
    

As you can see, we have prepared rules for each field separately. For example, we have provided an expression that will check if provided e-mail address is valid. If this is not a case, we will receive a message that "This field must be a valid email".

Step 4

Now we can start working on our form. You can follow our example by coping and pasting the code below to the App.vue file (or any other you created).

        
            
    <template>
      <MDBContainer class="my-5 py-5 w-50">
        <MDBCard>
          <MDBCardBody>
            <form ref="formRef">
              <div class="d-flex flex-wrap justify-content-between">
                <div
                  class="form-outline mb-4"
                  v-for="input in listOfFormElements"
                  :key="input.id"
                  :style="{ width: input.id > 3 ? '100%' : '47.5%' }"
                >
                    <MDBInput
                      :name="input.name"
                      :type="input.type"
                      :label="input.label"
                    />
                </div>
              </div>
              <div class="form-outline mb-4">
                  <MDBTextarea
                    rows="4"
                    label="Additional information"
                  ></MDBTextarea>
              </div>
              <div
                class="form-check d-flex justify-content-center mb-4"
                style="padding-left: 0"
              >
                  <MDBCheckbox
                    class="me-2"
                    label="Confirm the data"
                  />
              </div>
              <MDBBtn type="submit" color="primary" class="btn-block mb-4">
                Place order
              </MDBBtn>
            </form>
          </MDBCardBody>
        </MDBCard>
      </MDBContainer>
    </template>
    
        
    
        
            
    <script setup lang="ts">
      import {
        MDBContainer,
        MDBInput,
        MDBCheckbox,
        MDBTextarea,
        MDBBtn,
        MDBCard,
        MDBCardBody,
      } from "mdb-vue-ui-kit";
      
      import { ref } from "vue";
      
      const listOfFormElements = ref([
        { id: 0, name: "name", type: "text", label: "First name" },
        { id: 1, name: "lastname", type: "text", label: "Last name" },
        { id: 2, name: "address", type: "text", label: "Address" },
        { id: 3, name: "country", type: "text", label: "Country" },
        { id: 4, name: "email", type: "email", label: "Email" },
        { id: 5, name: "phone", type: "number", label: "Phone" },
      ]);
      
      const formRef = ref<HTMLFormElement | null>(null);
      </script>
    
    
        
    

This is the form we are going to validate. MDBInput can receive properties which will show if the field is validated correctly or not. To read more about this, visit our MDB Vue validation page where we explain how it works.

Step 5

The last thing we have to do is to connect VeeValidation with the one we have in mdb vue package. We need to import two things, useForm and Field.

        
            
    <template>
      <MDBContainer class="my-5 py-5 w-50">
        <MDBCard>
          <MDBCardBody>
            <form @submit.prevent="checkForm" novalidate ref="formRef">
              <div class="d-flex flex-wrap justify-content-between">
                <div
                  class="form-outline mb-4"
                  v-for="input in listOfFormElements"
                  :key="input.id"
                  :style="{ width: input.id > 3 ? '100%' : '47.5%' }"
                >
                  <Field
                    :name="input.name"
                    :rules="getRule(input.name)"
                    v-slot="{ handleChange, value, errorMessage }"
                  >
                    <MDBInput
                      :name="input.name"
                      :type="input.type"
                      :label="input.label"
                      :modelValue="getValue(value)"
                      @update:modelValue="handleChange"
                      :is-valid="!Boolean(errorMessage)"
                      :isValidated="validated"
                      :invalidFeedback="errorMessage"
                      :validFeedback="okFeedback"
                    />
                  </Field>
                </div>
              </div>
              <div class="form-outline mb-4">
                <Field
                  name="info"
                  :rules="getRule('info')"
                  v-slot="{ handleChange, value, errorMessage }"
                >
                  <MDBTextarea
                    rows="4"
                    label="Additional information"
                    :modelValue="getValue(value)"
                    @update:modelValue="handleChange"
                    :is-valid="!Boolean(errorMessage)"
                    :isValidated="validated"
                    :invalidFeedback="errorMessage"
                    :validFeedback="okFeedback"
                  ></MDBTextarea>
                </Field>
              </div>
    
              <div
                class="form-check d-flex justify-content-center mb-4"
                style="padding-left: 0"
              >
                <Field
                  name="checkbox"
                  :rules="getRule('checkbox')"
                  v-slot="{ handleChange, value, errorMessage }"
                >
                  <MDBCheckbox
                    class="me-2"
                    label="Confirm the data"
                    :modelValue="getBooleanValue(value)"
                    @update:modelValue="handleChange"
                    :is-valid="!Boolean(errorMessage)"
                    :isValidated="validated"
                    :invalidFeedback="errorMessage"
                    :validFeedback="okFeedback"
                  />
                </Field>
              </div>
              <MDBBtn type="submit" color="primary" class="btn-block mb-4">
                Place order
              </MDBBtn>
            </form>
          </MDBCardBody>
        </MDBCard>
      </MDBContainer>
    </template>
    
        
    
        
            
    <script setup lang="ts">
      import {
        MDBContainer,
        MDBInput,
        MDBCheckbox,
        MDBTextarea,
        MDBBtn,
        MDBCard,
        MDBCardBody,
      } from "mdb-vue-ui-kit";
      import { useForm, Field } from "vee-validate";
      import validationRules from "./validationRules";
      import type { RuleExpression } from "vee-validate";
      
      import { ref } from "vue";
      
      const getRule = (name: string) => {
        return validationRules[
          name as keyof typeof validationRules
        ] as RuleExpression<unknown>;
      };
      
      const getValue = (value: unknown) => {
        return value as string;
      };
      const getBooleanValue = (value: unknown) => {
        return value as boolean;
      };
      
      const okFeedback = "Looks good!";
      
      const listOfFormElements = ref([
        { id: 0, name: "name", type: "text", label: "First name" },
        { id: 1, name: "lastname", type: "text", label: "Last name" },
        { id: 2, name: "address", type: "text", label: "Address" },
        { id: 3, name: "country", type: "text", label: "Country" },
        { id: 4, name: "email", type: "email", label: "Email" },
        { id: 5, name: "phone", type: "number", label: "Phone" },
      ]);
      
      const { handleSubmit, resetForm } = useForm();
      
      const formRef = ref<HTMLFormElement | null>(null);
      const validated = ref(false);
      
      function onInvalidSubmit() {
        validated.value = true;
      }
      
      const checkForm = handleSubmit((values) => {
        validated.value = true;
        alert("Success! Your data: " + JSON.stringify(values, null, 2));
      
        resetForm();
        validated.value = false;
      }, onInvalidSubmit);
      </script>
      
    
        
    

As you can see, a few things changed from the code before. We have imported useForm which would give us access to two methods. handleSubmit is responsible for submiting data. You can provide a callback as the first argument with code that will be called if each validation field passes, and another callback as the second argument with the function that will be called after validation failed.

The next thing is to wrap our inputs inside a Field component. This will allow us to inject rules that inputs must follow to pass the validation. We can pass data from v-slot to our MDBInput component properties to see information if inputs are validated correctly.

That's it! Everything should work properly after clicking the submit button. If validation was unsuccessful, you should see information under each field that failed. After successful validation, you will receive an alert with data from your form, and after closing the alert resetForm method will clear the form.


More about VeeValidate

For more information, see VeeValidate page. There you can read about other options, best practices and testing.


Frontend features

MDB UI KIT:

To create the project we used our ui kit, with which we can build basic views very quickly.

Views and Layouts:

In this project we used HelloWorld.vue file, created by vite tool in which we placed our vue code. We have successfully integrated i18n into the MDB package and can use the appropriate translations based on provided json files.