Why Vuetify’s native form validation sucks

Orkhan Huseynli
5 min readMar 5, 2021

--

Introduction

Form validation is the crucial part of any web application. The users won’t always know how to fill your form and most of them will need a guidance. Thus, it’s crucial for us — front end developers — to define visually (and semantically) which inputs are required, and what kind of data the user needs to fill in. For this purpose, we may use native HTML5 form validation or some library to do more advanced and visually appealing form validations. In this article we’re going to talk about Vuetify’s form validation, what it lacks and why you might wanna use third party library instead of using rules prop.

Form validation with Vuetify

Vuetify is popular UI library for Vue that implements material design. It has plenty of components, utility classes and themes that may be handy if you want to build web applications in short time slot without worrying about cross-browser compatibility and performance. Let’s look at how we can use Vuetify to validate a form.

If we look at the docs about form validation we’ll see three options. Two of the options tell us to use vee-validate and vuelidate libraries and the first one shows us how we can use rules prop to validate the form.

Let’s say I do not want to use third party library to keep my app’s bundle size small or for some other reason. For that, I should add rules prop to the form element which is just an array of functions that return either true or some string value (error message). Here is how it looks like:

example of vuetift’s native form validation

To trigger the validation and check if the form is valid, we need to use methods that v-form has. According to the docs, validate method validates all registered inputs and returns true if validation was successful and false otherwise. Following the docs, the handleSubmit method would look like this:

handleSubmit method with Vuetify’s native form validation

Now, this process is quite straightforward, we can look at what the problem is.

The problem

Let’s say we want to add another input, which requires validation with external API. If you dig into the documentation, you’ll find out that there is no way to use async function for the rules prop. So, if you imagined something like below, this is not going to work:

async validation with rules prop

The only way to validate form element with an API is to use error , error-messages and error-count props. These props just set the validation state of the form element:

manual validation with error props

To test this, lets’s add the second input with error-messages into the form:

invalid text-field with error and error-messages

Now what happens if we hit submit button? Go to the sandbox I have created, click the submit button and look at the console. Although we have marked the second input as invalid, this.$refs.form.validate() will return true. This is not an expected behavior in both from developer perspective and from user perspective. In this case, the API request will still be made even though the surname input is invalid (a.k.a has error-messages). So what is the cause of this problem?

The cause

To see the reason behind this logic, let’s dive into Vuetify’s source code. Let’s start from VForm component and see how validate method works:

validate method from Vuetify’s source code

Validate method takes all the inputs the form has, calls validate method on them and filters them to find if there is an invalid input or not. If you look at the VTextField component, you will see that there isn’t any method named validate . This is because all form elements implement validatable mixin which has all the properties and methods that a validatable form element has. Let’s look inside of validatable mixin and see what validate method does:

inside the validate method

As you see, it calls all the functions that the rules prop has, pushes the error messages (if there are any) into the variable called errorBucket and finally checks if error bucket is empty or not. If empty then this input element is valid. The error-messages prop that we passed to our second element is accepted as a prop and is not being checked inside validate method. So the error-messages prop is for visual purpose only.

The solution

Possible solutions for the case above would be to use async for loop to be able to run rules that contain async functions or check the errorMessages props along with errorBucket or copy the errorMessages prop to errorBucket variable on mount .

I have opened an issue on this one and it was closed saying that this is not a feature they want to implement for now 🐵.

Conclusion

Take home lesson from this article would be — Do not rely on Vuetify’s native form validation. If you will need some extended functionality on validation (like API validation) use libraries like vee-validate or vuelidate.

Thanks for reading and do not hesitate to reach me out or comment below, if you think I am missing something or you have an alternative approach to solve this issue.

--

--

Responses (2)