I have a Vue.js text-input
component like the following:
<template>
<input
type="text"
:id="name"
:name="name"
v-model="inputValue"
>
</template>
<script>
export default {
props: ['name', 'value'],
data: function () {
return {
inputValue: this.value
};
},
watch: {
inputValue: function () {
eventBus.$emit('inputChanged', {
type: 'text',
name: this.name,
value: this.inputValue
});
}
}
};
</script>
And I am using that text-input
in another component as follows:
<ul>
<li v-for="row in rows" :key="row.id">
<text-input :name="row.name" :value="row.value">
</text-input>
</li>
</ul>
Then, within the JS of the component using text-input
, I have code like the following for removing li
rows:
this.rows = this.rows.filter((row, i) => i !== idx);
The filter
method is properly removing the row that has an index of idx
from the rows
array, and in the parent component, I can confirm that the row is indeed gone, however, if I have, for example, two rows, the first with a value of 1
and the second with a value of 2
, and then I delete the first row, even though the remaining row has a value of 2
, I am still seeing 1
in the text input.
Why? I don't understand why Vue.js is not updating the value of the text input, even though the value of value
is clearly changing from 1
to 2
, and I can confirm that in the parent component.
Maybe I'm just not understanding how Vue.js and v-model
work, but it seems like the value of the text input should update. Any advice/explanation would be greatly appreciated. Thank you.
You cannot mutate values between components like that.
Here is a sample snippet on how to properly pass values back and forth. You will need to use computed setter/getter. Added a button to change the value and reflect it back to the instance. It works for both directions.
<template>
<div>
<input type="text" :id="name" v-model="inputValue" />
<button @click="inputValue='value2'">click</button>
</div>
</template>
<script>
export default {
props: ['name', 'value'],
computed: {
inputValue: {
get() {
return this.value;
},
set(val) {
this.$emit('updated', val);
}
}
}
}
</script>
Notice that the "@updated" event updates back the local variable with the updated value:
<text-input :name="row.name" :value="row.value" @updated="item=>row.value=item"></text-input>