As the documentation states, v-model directive on input element provides syntax sugar for a combination of bound value prop and input event handler.
Based on this question, an input fails to synchronize with bound value when used with input event handler that transforms a value:
new Vue({
template: '<input :value="val" @input="onUpdate" />',
data: () => ({ val: '' }),
methods: {
onUpdate(e) {
this.val = e.target.value.replace(/\s/g, "");
console.log('val', this.val);
}
},
}).$mount('#app')
<script src="https://unpkg.com/vue@2.7.10/dist/vue.js"></script>
<div id="app"></div>
A demo:
The same input works as intended when used with v-model and a watcher, as described in this answer:
new Vue({
template: '<input :value="val" @input="onUpdate" />',
data: () => ({ val: '' }),
methods: {
onUpdate(e) {
this.val = e.target.value;
}
},
watch: {
val: {
handler(val) {
this.val = val.replace(/\s/g, "");
console.log('val', this.val);
},
immediate: true
}
},
}).$mount('#app')
<script src="https://unpkg.com/vue@2.7.10/dist/vue.js"></script>
<div id="app"></div>
Doing this in the same handler also fixes the problem:
onUpdate(e) {
this.val = e.target.value;
this.val = this.val.replace(/\s/g, "");
}
What does happen here? Why does the direct assignment of transformed value to val doesn't work, but doing this in two steps does?
This problem applies to both Vue 2 and 3.
