Home > Software design >  Vuetify vform validation result in watch is delayed
Vuetify vform validation result in watch is delayed

Time:11-25

I have a real simple form here

  <div id="app">
    <h3>form Valid: {{ formValid }}</h3>
    <h3>input: {{ input }}</h3>
    <v-form ref="testForm" v-model="formValid">
      <v-text-field
        v-model="input"      
        :rules="nameRules"
        required
      ></v-text-field>
    </v-form>
 </div>

With an UI like this
1

I have a watch property on input which should print the formValid status for every keystroke
2

However it will print false for the first letter but then true for the latter. It seems the form valid status is delayed once.
3

I guess it's related to vue life-cycle hooks but I have no idea where to start with :/ Thanks for the help!
Code Pen

CodePudding user response:

At the moment your watch method is executed, the value of formValid is being displayed by the console at that precise moment, when the rule included as a computed property has not yet been executed (or anything else). Therefore at that moment the value of formValid is the one prior to the execution of nameRules and that is why with the writing of the first character it is false and with the writing of the tenth character it is still true. If what you want is to fire an event from the validation of the form, you can create another watch on the formValid data property.

CodePudding user response:

Check this codesandbox I made: https://codesandbox.io/s/stack-70093759-d82kf?file=/src/components/TestForm.vue

I was able to replicate the issue in the watcher, yeah, I looks like on the first letter returns false, I guess it could be something about the life cycle of vue. Instead of using a watcher you can call a method using the @keyup event of the v-text-field

      <v-text-field
      v-model="input"      
      :rules="nameRules"               
      counter="10"
      required
      @keyup="logThis"
      ></v-text-field>

The way you're trying to configure the validation rule as a computed property looks a bit weird for me. I usually define them in the data block like this.

   data: () => ({
     formValid: true,
     input: '',
     nameRules: [
         (v) => !!v || 'Name is required',
         (v) => (v && v.length <= 10) || 'Name must be less than 10 characters'
      ]
   }),
    methods: {
      submitForm() {
         if (this.$refs.testForm.validate()) {
            // Do something ...
         }
      },
      logThis() {         
         console.log(this.formValid)
      }
   },

You can also set the formValid as true and use the lazy-validation prop of the v-form. I also added a submit button to trigger the validate() method of the form.

Example

  • Related