Creating a web form is an essential skill for any web developer. In this post, I will share with you my tools and workflow to create a reliable multilingual web form.
To follow with me, you must be a little bit comfortable with Vuejs basics (like how to create a new app).
Let's go step by step:
Setup
within your vue app:
npm install vee-validate @vee-validate/rules vue-i18n@9
Initialization
1- Create i18n instance with options:
import { createI18n } from 'vue-i18n';
import en from '../../locales/en.json';
import ar from '../../locales/ar.json';
const i18n = createI18n({
legacy: false,
locale: 'en',
fallbackRoot: 'en',
messages: {en, ar}
});
If you faced this warning message:
You are running the esm-bundler build of vue-i18n. It is recommended to configure your bundler ...
this can be solved by configuring Vite:
resolve: {
alias: {
'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js'
}
}
2- Declare vee-validate
components (VeeForm and VeeField) as global components within a Vuejs custom plugin to make them available anywhere within the app:
import {
Form as VeeForm,
Field as VeeField,
} from 'vee-validate';
export default {
install(app) {
app.component('VeeForm', VeeForm);
app.component('VeeField', VeeField);
}
}
Next task is to add validation rules, and for that vee-validate
offers a wide range of common validators that you can use, they are packaged in @vee-validate/rules
.
In order to generate custom validation error messages, vee-validate
must be configured through generateMessage
property:
import {
defineRule
configure
} from 'vee-validate';
import { required, email, confirmed } from '@vee-validate/rules';
export default {
install(app) {
...
defineRule('required', required);
defineRule('email', email);
defineRule('confirmed', confirmed);
configure({
generateMessage: (ctx) => {
const messages = {
'required': `${ctx.field}.errors.required`,
'email': `${ctx.field}.errors.email`,
'confirmed': `${ctx.field}.errors.confirmed`
};
return messages[ctx.rule.name]
}
});
}
}
3- Bring everything together here:
import { createApp } from 'vue';
import { createI18n } from 'vue-i18n';
//includes
import veevalidate from './plugins/veevalidate.js';
//locales
import en from '../../locales/en.json';
import ar from '../../locales/ar.json';
import App from '../../components/vue/multilingual-register-form/index.vue';
//parts
const i18n = createI18n({
legacy: false,
locale: 'en',
fallbackRoot: 'en',
messages: {en, ar}
});
createApp(App).use(i18n).use(veevalidate).mount('#app');
Create the form
1- VeeForm component (vee-form) has a lot of useful props. You can assign a custom validation schema (for example) through the validation-schema
prop:
const validationSchema = {
'name': 'required',
'email': 'required|email',
'password': 'required',
'confirm-password': 'confirmed:@password'
};
2- VeeField component (vee-field) will wrap a single form input element and make use of the scoped-slots (v-slot) feature to allow you to render complex markup:
<vee-form
class="px-4 text-4xl"
:validation-schema="validationSchema"
@submit="register"
v-slot={errors}
>
...
<div class="mt-8 flex flex-col justify-center">
<label for="name" class="font-ssp font-bold capitalize">{{ $t(prepForTrans("name.label")) }}</label>
<vee-field name="name" v-slot="{field, errors}">
<input type="text" class="p-4 mt-4 border-2 border-black" v-bind="field">
<div class="font-mont font-bold text-3xl text-red-600 mt-2" v-if="errors.length > 0">
{{ $t(prepForTrans(errors[0] || "")) }}
</div>
</vee-field>
</div>
...
<div class="mt-8">
<button :class="['font-ssp font-bold uppercase p-4 w-full bg-black text-4xl text-white', {'opacity-50 cursor-not-allowed': Object.keys(errors).length}]" type="submit">
{{ $t(prepForTrans("btns.submit")) }}
</button>
</div>
</vee-form>
Conclusion
VeeValidate is the most popular and powerful Vue.js form library. It takes care of value tracking, validation, errors, submissions, and more. By using it you will be able to create and validate any web form thrown at you.
Your feedback is much appreciated, thank you for reading.
Top comments (0)