Gnopps
Gnopps

Reputation: 349

Adding element to array that has v-model causes duplicate

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

Answers (2)

DobleL
DobleL

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

Boussadjra Brahim
Boussadjra Brahim

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

Related Questions