Problem Statement : I just migrated my Vue 2 application (Contains Vuetify 2) into Vue 3 (with Vuetify 3). After migrating, validate() method on form is not working as expected. It always return truthy value if still there are errors in the form fields.
(this.$refs.myForm as any & { validate: () => boolean }).validate()
OR
(this.$refs.myForm as any).validate()
Above line of code always returns promise (Assuming a truthy value).
Here is the link
of Vuetify playground (Vue: 3.3.4 and Vuetify: 3.3.7)
What I tried so far ?
I tried to find the root cause of the issue and come up with the conclusion that this.$refs.myForm.validate()
returns a promise (I think compiler assumes that as a truthy value).
I think I can achieve this by adding the v-model
attribute in the form element and then on submit, I can check the form v-model
value. Is this approach correct ? Or I have to change something in the original approach to make it work ?
Here is the playground link
as per this approach.
If I am using both the solutions together, It is working as per the expectation (Showing validation errors and preventing the submit if form has any error).
Template :
<v-form ref="myForm" v-model="valid">
Script :
On submit button @click
event
if ((this.$refs.myForm as any & { validate: () => boolean }).validate() && this.valid) {
...
}
Above solution works fine but Still thinking about best approach. If I will use validate using VForm v-model
, It is only preventing the submit if there is any errors but not highlighting the errors.
Update :
I implemented the solution suggested by Neha
and it is working fine as per the requirement. The only thing which I noticed is that If I am assigning validation rules on a button click event method, validation not trigger for the first field on first click but working fine on another click. Here is the Vuetify playground
of the issue.
To get rid from this issue, I am using nextTick
utitlity of vue
and now it is validating all the fields at first click itself. Here is the working playground
. Any input/suggestion on this ?
In Vuetify 3, the validate
method returns the promise which can get resolved either using await
or chaining the response using .then()
. An example in documentation also demonstrates that see here.
So, one approach for this problem could be using a ref
variable on the form and on submit, simply call the validate()
method and chain its response to extract the valid
param which tells the validation status.
I used script setup
in the demo. Here is the possible solution-
<template>
<v-form ref="myForm">
<v-container>
<v-row>
<v-col cols="12" md="4">
<v-text-field
v-model="firstname"
:rules="nameRules"
:counter="10"
label="First name"
required
></v-text-field>
</v-col>
</v-row>
<v-btn type="submit" color="primary" @click="submitForm">Submit</v-btn>
</v-container>
</v-form>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const myForm = ref();
const firstname = ref(null);
const nameRules = [
value => {
if (value) return true
return 'Name is required.'
},
value => {
if (value?.length <= 10) return true
return 'Name must be less than 10 characters.'
},
]
const submitForm = () => {
myForm.value?.validate().then(({valid: isValid}) => {
console.log(isValid);
})
}
</script>
Here is the working demo.
Hope this helps.