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.
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.