Search code examples
javascriptvue.jsvuejs2v-forv-model

Dynamics inputs, the v-model update all values in v-for


I try this following code with Vue.js 2:

<div id="app">
  <div v-for="(item, index) in items">
    <div>
      <input type="text" v-model="items[index].message">
      <input type="text" v-model="items[index].surface">
    </div>    
  </div>
<button @click="addNewfield">Add</button>
</div>

var app = new Vue({
  el: '#app',
  data: {
    item: {
      message: 'test',
      surface: 45
    },
    items: [],
  },
  mounted() {
    this.items.push(this.item)
  },
  methods: {
    addNewfield() {
      this.items.push(this.item);
    }
  }
})

The goal is to create news input when user click on Add button. I tried different ways like :

<input type="text" v-model="item.message">

But it doesn't work. If you write in "message" input, all "message" inputs will be updated.

How can I only updated the concerned value ?

Thanks for help !


Solution

  • This is happening because objects in Javascript are stored by reference. This means that every time you push this.item onto the array, it's adding a reference to the exact same object as the last.

    You can avoid this by creating a new object each time:

    methods: {
      addNewfield() {
        const obj = {
          message: 'test',
          surface: 45
        } 
        this.items.push(obj);
      }
    }
    

    Another option would be to clone the original object each time like:

    methods: {
      addNewfield() {
        const clone = Object.assign({}, this.item);
        this.items.push(clone);
      }
    }