How to Validate Form in Vue 3 with VeeValidate
In this tutorial, we will learn how to create a responsive web form using the BootstrapVue front-end CSS library and validate that Form using the Template-Driven approach using VeeValidate Form Validation Framework.
The template-driven approach is nothing but the simple way which allows you to validate your forms by combining attributes to inputs.
This can be very easily achieved in Vue by taking the help of vee-validate package.
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"
},
Vue multi word error
To remove multi-word error warning, add the following code in vue.config.js file.
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
})
Why Form Validation Needed?
Form validation is essential to protect forms by sending abusive emails by malicious users. Incorrect submission of form data may lead to a breach of security.
Non validated forms may invite hackers to attacks using header injections, cross-site scripting, and SQL injections methods.
We are going to build a simple user registration form with necessary input fields such as name, email, mobile number, city, password, confirm password, and hobbies.
In this form, every field will be a required field along with that we will have email validation and password confirmation validation applied to the input fields.
To add the styling, we used a bootstrap-vue package, which is an alternative to Bootstrap 4 for the Vue environment.
Install VeeValidate
To install vee-validate
package, run either of the commands among Yarn or NPM package manager.
npm install vee-validate
Next, open your main.js
file and add the following code inside of it to initiate the vee-vulidate package.
import { ValidationObserver, ValidationProvider, extend } from 'vee-validate';
import * as rules from 'vee-validate/dist/rules';
// install rules
Object.keys(rules).forEach(rule => {
extend(rule, rules[rule]);
});
Vue.component('ValidationObserver', ValidationObserver);
Vue.component('ValidationProvider', ValidationProvider);
Adding Bootstrap in Vue
Adding Bootstrap 4 in the Vue application is easy. We have to run the given below command to add the BootstrapVue plugin.
npm i bootstrap-vue
BootstrapVue, with over 40 available plugins, more than 80 custom components, and over 530 icons, provides one of the most comprehensive implementations of the Bootstrap v4 component and grid system for Vue.js, complete with extensive and automated WAI-ARIA accessibility markup.
Next, again go to main.js
file and add the Bootstrap required services to enable the plugin.
import Vue from "vue";
import { ValidationObserver, ValidationProvider, extend } from 'vee-validate';
import * as rules from 'vee-validate/dist/rules';
import App from "./App.vue";
import BootstrapVue from 'bootstrap-vue';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';
// install rules
Object.keys(rules).forEach(rule => {
extend(rule, rules[rule]);
});
// Install components globally
Vue.use(BootstrapVue);
Vue.component('ValidationObserver', ValidationObserver);
Vue.component('ValidationProvider', ValidationProvider);
Vue.config.productionTip = false;
new Vue({
render: h => h(App)
}).$mount("#app");
Create Form with Bootstrap in Vue
In this step, we are going to create a basic form. Let us add the following code inside the Vue template. This code contains the HTML code that will display the beautiful and user-centric form on the user’s browser.
<template>
<b-form @submit.prevent="handleSubmit">
<b-form-group label="Name">
<b-form-input
type="text"
v-model="user.name"
placeholder="Enter name">
</b-form-input>
</b-form-group>
<b-form-group label="Email">
<b-form-input
type="email"
v-model="user.email"
placeholder="Enter email">
</b-form-input>
</b-form-group>
<b-form-group label="Mobile">
<b-form-input
type="text"
v-model="user.mobile"
placeholder="Enter mobile no">
</b-form-input>
</b-form-group>
<b-form-group label="City">
<b-form-select v-model="user.city">
<option value="">Choose</option>
<option value="CA">Los Angeles</option>
<option value="IL">Chicago</option>
<option value="LA">New Orleans</option>
<option value="NM">Santa Fe</option>
</b-form-select>
</b-form-group>
<b-form-group label="Password">
<b-form-input v-model="user.password" type="password" placeholder="Enter password">
</b-form-input>
</b-form-group>
<b-form-group label="Confirm Password">
<b-form-input v-model="user.confirmation" type="password"></b-form-input>
</b-form-group>
<b-form-group>
<b-form-checkbox-group v-model="user.hobbies">
<b-form-checkbox value="Reading">Reading</b-form-checkbox>
<b-form-checkbox value="Gyming">Gyming</b-form-checkbox>
<b-form-checkbox value="Movies">Movies</b-form-checkbox>
</b-form-checkbox-group>
</b-form-group>
<b-button block type="submit" variant="primary">Submit</b-button>
</b-form>
</template>
<script>
export default {
data: () => ({
user:{
name: '',
email: '',
mobile: '',
city: '',
password: '',
confirmation: '',
hobbies: []
}
}),
methods: {
handleSubmit () {
console.log(this.user);
}
}
};
</script>
<style lang="scss">
form {
max-width: 500px;
margin: 0 auto;
text-align: left;
}
.col-form-label {
font-weight: 600;
}
</style>
Vue Form Validation with VeeValidate
We already registered the ValidationProvider in main.js
file, and It acts as a validator for your fields, it works via scoped-slots to provide validation errors to your template.
The v-model directive bind input field properties with user form object in the Vue app. The VeeValidate plugin made the Template-Driven approach easy to be added with rules.
Rules support a lot of standard validators that are sufficient to add validation like min, max, image, alpha, email, size, required, regex, numeric integer, and many more.
We bind the handleSubmit() method with submitting event something like this @submit.prevent=”handleSubmit” event.
Here, prevent method cancels the event if it is cancelable, meaning that the default action that belongs to the event will not occur.
Initially, we are showing the Validation messages when the user clicks on the submit button.
<template>
<ValidationObserver ref="observer">
<b-form slot-scope="{ validate }" @submit.prevent="validate().then(handleSubmit)">
<ValidationProvider rules="required" name="Name">
<b-form-group slot-scope="{ valid, errors }" label="Name">
<b-form-input
type="text"
v-model="user.name"
:state="errors[0] ? false : (valid ? true : null)"
placeholder="Enter name">
</b-form-input>
<b-form-invalid-feedback>
{{ errors[0] }}
</b-form-invalid-feedback>
</b-form-group>
</ValidationProvider>
<ValidationProvider rules="required|email" name="Email">
<b-form-group
slot-scope="{ valid, errors }"
label="Email">
<b-form-input
type="email"
v-model="user.email"
:state="errors[0] ? false : (valid ? true : null)"
placeholder="Enter email">
</b-form-input>
<b-form-invalid-feedback>
{{ errors[0] }}
</b-form-invalid-feedback>
</b-form-group>
</ValidationProvider>
<ValidationProvider rules="required" name="Mobile">
<b-form-group
slot-scope="{ valid, errors }"
label="Mobile">
<b-form-input
type="text"
v-model="user.mobile"
:state="errors[0] ? false : (valid ? true : null)"
placeholder="Enter mobile no">
</b-form-input>
<b-form-invalid-feedback>
{{ errors[0] }}
</b-form-invalid-feedback>
</b-form-group>
</ValidationProvider>
<ValidationProvider name="City" rules="required">
<b-form-group slot-scope="{ valid, errors }" label="City:">
<b-form-select
:state="errors[0] ? false : (valid ? true : null)"
v-model="user.city">
<option value="">Choose</option>
<option value="CA">Los Angeles</option>
<option value="IL">Chicago</option>
<option value="LA">New Orleans</option>
<option value="NM">Santa Fe</option>
</b-form-select>
<b-form-invalid-feedback>
{{ errors[0] }}
</b-form-invalid-feedback>
</b-form-group>
</ValidationProvider>
<ValidationProvider rules="required" name="Password" vid="password">
<b-form-group
slot-scope="{ valid, errors }"
label="Password">
<b-form-input
type="password"
v-model="user.password"
:state="errors[0] ? false : (valid ? true : null)"
placeholder="Enter password">
</b-form-input>
<b-form-invalid-feedback>
{{ errors[0] }}
</b-form-invalid-feedback>
</b-form-group>
</ValidationProvider>
<ValidationProvider rules="required|confirmed:password" name="Confirm Password">
<b-form-group
slot-scope="{ valid, errors }"
label="Confirm Password">
<b-form-input
type="password"
v-model="user.confirmation"
:state="errors[0] ? false : (valid ? true : null)">
</b-form-input>
<b-form-invalid-feedback>
{{ errors[0] }}
</b-form-invalid-feedback>
</b-form-group>
</ValidationProvider>
<ValidationProvider name="Hobbies" rules="required|length:1">
<b-form-group slot-scope="{ valid, errors }">
<b-form-checkbox-group
:state="errors[0] ? false : (valid ? true : null)"
v-model="user.hobbies">
<b-form-checkbox value="Reading">Reading</b-form-checkbox>
<b-form-checkbox value="Gyming">Gyming</b-form-checkbox>
<b-form-checkbox value="Movies">Movies</b-form-checkbox>
</b-form-checkbox-group>
<b-form-invalid-feedback>
{{ errors[0] }}
</b-form-invalid-feedback>
</b-form-group>
</ValidationProvider>
<b-button block type="submit" variant="primary">Submit</b-button>
</b-form>
</ValidationObserver>
</template>
<script>
import { ValidationObserver, ValidationProvider } from 'vee-validate';
export default {
components: {
ValidationObserver,
ValidationProvider
},
data: () => ({
user:{
name: '',
email: '',
mobile: '',
city: '',
password: '',
confirmation: '',
hobbies: []
}
}),
methods: {
handleSubmit () {
console.log(this.user);
}
}
};
</script>
<style lang="scss">
form {
max-width: 500px;
margin: 0 auto;
text-align: left;
}
.form-group > label {
font-weight: 600;
}
</style>
Summary
We just learned to create Forms in Vue and also looked at how to add validation using vee-validate plugin. It makes validating HTML inputs and Vue components super easy.