[Vuejs]-SetCustomValidity is only applied on the 2nd click

0👍

EDIT: alright, a far more easier way of writing things would be the following (if the end goal is to check the equality of 2 fields):

<template>
  <div>
    <form @submit.prevent="checkPasswordFields">
      <input v-model="password" placeholder="input password" />
      <input v-model="passwordConfirmation" placeholder="confirm password" />
      <button>submit</button>
    </form>

    <p>do password match ? >> {{ doPasswordMatch }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      password: '',
      passwordConfirmation: '',
    }
  },
  methods: {
    checkPasswordFields() {
      console.log(`Password do${this.doPasswordMatch ? '' : ' not'} match !`)
    },
  },
  computed: {
    doPasswordMatch() {
      return this.password === this.passwordConfirmation
    },
  },
}
</script>

This is probably coming from the fact that your DOM did not re-render before passing into your setCustomValidity method. Depending when you do have your condition, Vue may have not yet updated it’s state.

First off, you should switch your document.getElementById to $refs as explained here: https://v2.vuejs.org/v2/guide/components-edge-cases.html#Accessing-Child-Component-Instances-amp-Child-Elements

So, it may look something like

<base-input ref="passwordConfirmation"></base-input>

and then, you do select your element with

this.$refs.passwordConfirmation

This alone, may maybe fix the issue.


If it’s not enough, you may also squeeze a

await this.$nextTick()

before your condition. That way, you will wait for Vue to update it’s state before proceeding.

Of course, there may be a more usual way of doing this without relying on the nextTick hack, but it all comes down to your code logic here and we will need more of it.

A good clean alternative is to use the package vee-validate, which will help you make more concise and better structured front-end validations: https://vee-validate.logaretm.com/v3/guide/rules.html#confirmed


To answer the last part of your question: it does happen the 2nd time because Vue has it’s state updated on the 2nd run.

Leave a comment