<\/figure>\nWe can see in data<\/code> that we have… well, me typing like a lunatic. But let\u2019s check out some of these other fields. $dirty<\/code>, in this case, refers to whether the form has been touched at all. We can also see that the $model<\/code> field is now filled in for the name object, which mirrors what\u2019s in data<\/code>. <\/p>\n$error<\/code> and $invalid<\/code> sound the same but are actually a little different. $invalid<\/code> is checking if it passes validation, but $error<\/code> checks both<\/strong><\/em> for something that’s $invalid<\/code> and whether or not it’s $dirty<\/code> (whether the form has been touched yet or not). If this all seems like a lot to parse (haha get it? parse?), don’t worry, we’ll walk through many of these pieces step by step.<\/p>\nInstalling Vuelidate and creating our first form validation<\/h3>\n OK, so that was a very simple example. Let\u2019s build something real out of it. We\u2019ll bring this into our application and this time we\u2019ll make the field required and<\/em> give it a minimum length requirement. In the Vue app, we\u2019ll first add Vuelidate:<\/p>\nyarn add vuelidate<\/code><\/pre>\nNow, let\u2019s go into the main.js<\/code> file and update it as follows: <\/p>\nimport Vue from 'vue';\r\nimport Vuelidate from \"vuelidate\";\r\nimport App from '.\/App.vue';\r\nimport store from '.\/store';\r\n\r\nVue.use(Vuelidate);\r\nVue.config.productionTip = false\r\n\r\nnew Vue({\r\n store,\r\n render: h => h(App)\r\n}).$mount('#app')<\/code><\/pre>\nNow, in whatever component holds the form element, let\u2019s first import the validators we\u2019ll need:<\/p>\n
import { required, minLength } from 'vuelidate\/lib\/validators'<\/code><\/pre>\nThen, we\u2019ll put the data inside of a function so we can reuse the component. You likely know about that one. Next, we\u2019ll put our name<\/code> form field in an object, because typically, we’d want to capture all of the form data together. <\/p>\nWe\u2019ll also need to include the validations, which will mirror our data. We\u2019ll use required<\/code> again, but this time we\u2019ll also add a key\/value pair for the minimum length of the characters, minLength(x)<\/code>, which will look something like this:<\/p>\n<script>\r\nimport { required, minLength } from 'vuelidate\/lib\/validators'\r\n\r\nexport default {\r\n data() {\r\n return {\r\n formResponses: {\r\n name: '',\r\n }\r\n }\r\n },\r\n validations: {\r\n formResponses: {\r\n name: {\r\n required,\r\n minLength: minLength(2)\r\n },\r\n }\r\n }\r\n}\r\n<\/script><\/code><\/pre>\nNext, in the template, we\u2019ll create a label for accessibility purposes. Instead of using what\u2019s in the data to create the relationship in v-model<\/code>, we\u2019ll use that computed property ($model<\/code>) that we saw earlier in the validations<\/code> object. <\/p>\n<template>\r\n <div id=\"app\">\r\n <label for=\"fname\">Name*<\/label>\r\n <input id=\"fname\" class=\"full\" v-model=\"$v.formResponses.name.$model\" type=\"text\">\r\n <\/div>\r\n<\/template><\/code><\/pre>\nFinally, beneath the form input, we\u2019ll place some text beneath the form. We can use required<\/code> attached to formResponses.name<\/code> to see if it evaluates correctly and whether it\u2019s provided at all. We can also see if there\u2019s more than the minimum length of characters. We even have a params<\/code> object that will tell us the number of characters we specified. We\u2019ll use all of this to create informative error messages for our user.<\/p>\n<p class=\"error\" v-if=\"!$v.formResponses.name.required\">this field is required<\/p>\r\n<p class=\"error\" v-if=\"!$v.formResponses.name.minLength\">Field must have at least {{ $v.formResponses.name.$params.minLength.min }} characters.<\/p><\/code><\/pre>\nAnd we\u2019ll style our error class so it\u2019s clear at a glance that they\u2019re errors.<\/p>\n
.error {\r\n color: red;\r\n}<\/code><\/pre>\n