Reputation: 349
I've got a list of text input-fields created through a v-for with a v-model
to an array. I want to add elements to the array, and thus creating another input-field.
So far all works. The problem is that the new input-fields are somehow all assigned the same index (?) or something else is happening to cause them to display the same value.
I've made this jsfiddle to showcase what I mean. If you press the button twice and then try to edit one of the new input-boxes, then all the new input-boxes will get the edited value. I'd want only the edited input-box to show the input value.
I guess there is something I am overlooking here. Is there anyone who can help with this please?
Javascript:
new Vue({
el: '#app',
data: {
items: [{name: "one", id: 0}],
template: {
name: "two",
id: 2,
},
},
methods: {
addRow: function(){
this.items.push(this.template);
this.items[this.items.length - 1].id = Math.random();
}
}
})
HTML:
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div v-for="(item,index) in items" :key="item.id">
<input v-model="item.name">
</div>
<button v-on:click="addRow">
Add row
</button>
<div>Array content: {{items}}</div>
</div>
Usage: screenshot of what i'm getting
Upvotes: 3
Views: 2366
Reputation: 3928
The problem here is that with array.push(declaredObject)
you are adding a reference of template
so every change will be reflected in all its references.
You must add a new object with the same properties, you can achieve that in many ways, the more common is Object.assign({}, this.template)
and the newest one is Destructuring objects {...this.template}
. so in your case It should be this.items.push({...this.template})
Upvotes: 8
Reputation: 1
try
this.items.push({
name: "two",
id: 2,
});
instead of this.items.push(this.template)
because template
property is reactive and it will affect other properties that use it
check this fiddle
Upvotes: 2