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.