I have the following input:
<input :value="inputAmount" @input="handleAmountInput($event)" placeholder="Enter amount..." type="text">
I don't want 2-way binding with inputAmount
because I want to clean the input of non-numeric characters in the handleAmountInput()
function whenever the user inputs something:
handleAmountInput(e) {
const cleanInput = e.target.value.replace(/\D/g, '');
this.inputAmount = cleanInput;
console.log(cleanInput);
},
The issue is, the input itself doesn't reflect this cleaned up string set to inputAmount
. If I show inputAmount
in a separate element or console.log
it like in the snippet above, it shows up just fine, but binding the value to the input with :value
doesn't seem to work and shows the full inputted string, including non-numeric characters. What am I doing wrong here and how do I get the input to show the cleaned up string?
I'm not yet sure why exactly your code doesn't work as I would expect it to, but the way to fix it is to use both v-model
and @input
handler at the same time...
const app = Vue.createApp({
data() {
return {
inputAmount: ''
}
},
methods: {
handleAmountInput(e) {
this.inputAmount = e.target.value.replace(/\D/g, '');
console.log(this.inputAmount);
},
},
})
app.mount('#app')
<script src="https://unpkg.com/vue@3.1.5/dist/vue.global.js"></script>
<div id='app'>
<input v-model="inputAmount" @input="handleAmountInput($event)" placeholder="Enter amount..." type="text">
<pre>{{ inputAmount }}</pre>
</div>
Update
Ok, I now understand the reason why your code does not work. What happens:
inputAmount
is for example '123'
(reflected in <input>
)a
@input
handler is called. It receives the value '123a'
, do it's job creating cleaned value '123'
and assigns it into inputAmount
inputAmount
did not changed at all so no re-render is required and <input>
still shows '123a'
even tho inputAmount
has a value of '123'
So another way of fixing your code is just to assign some value <input>
can never produce into inputAmount
1st just to trigger the update (demo below)
const app = Vue.createApp({
data() {
return {
inputAmount: ''
}
},
methods: {
handleAmountInput(e) {
this.inputAmount = null
this.inputAmount = e.target.value.replace(/\D/g, '');
console.log(this.inputAmount);
},
},
})
app.mount('#app')
<script src="https://unpkg.com/vue@3.1.5/dist/vue.global.js"></script>
<div id='app'>
<input :value="inputAmount" @input="handleAmountInput($event)" placeholder="Enter amount..." type="text">
<pre>{{ inputAmount }}</pre>
</div>