0

My own vue component sends http request to receive array of objects, then I store the answer in data property, and it's fine. Now I want to bind this array to v-model, but when user will input something my array is changed too. I want to store the array for later and make it not editable, I just want to bind its value to v-model, not reference to my array. My target is to allow user to reset v-model value to array received from api. I hope you get the point and you will be able to help me.

<draggable v-model="myArray">
   <div v-for="element in myArray" :key="element.id">{{element.name}}</div>
</draggable>
<button @click="addElement">New</button>
data() {
   return {
       myArray: [],
       array: []
   }
},
methods: {
   addElement() {
      myArray.push({id:1, name:'something'});
   },
   getData() {
      axios(...)
      .then(res => {
         this.array = response.data;
      });
   }
   setData() {
      this.myArray = this.array;
   }
}

Now if user will add new element to myArray it will be also inserted in array

2
  • Have you tried pass cloned array using array.map, array.filter or something similar? Commented Feb 27, 2020 at 17:25
  • I've updated post, now you can see the code, @Darius, yeah I've tried this, but got the same result. Commented Feb 27, 2020 at 19:41

2 Answers 2

2

Data must be cloned:

new Vue({
  template: '<div>List1:<ul><li v-for="i in array1" :key="i.id">{{i.name}}</li></ul>List2:<ul><li v-for="i in array2" :key="i.id">{{i.name}}</li></ul><button @click="add">Add</button></div>',
  data: {
    array1: [{id:1, name:'Item1'},{id:2, name:'Item2'}],
    array2: []
  },
  created() {
    // clone array
    this.array2 = this.array1.map(i => Object.assign({},i))
  },
  methods: {
    add() {
      this.array1.push({id:this.array1.length+1, name:'Item'+(this.array1.length+1)})
      this.array1[0].name = 'Item1/' + this.array1.length
    }
  }
}).$mount('div')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div></div>

If it is more complex array of objects, then must use some sort of deep-clone.

Sign up to request clarification or add additional context in comments.

1 Comment

I've tried with Object.create instead of Object.assign, that's the problem, thanks a lot!
1

I solved a similar issue using the JSON parse to make the to-be-copied-array loose dinamic relation with the array-to-be-created. Try the following:

data() {
   return {
       myArray: [],
       array: []
   }
},
methods: {
   addElement() {
      myArray.push({id:1, name:'something'});
   },
   getData() {
      axios(...)
      .then(res => {
         this.array = response.data;
      });
   }
   setData() {
      this.myArray = JSON.parse(JSON.stringify(this.array)); // Here goes the trick
   }
}

This way every change on v-model array by the user won't be reflected on myArray since the setData() is called at least once before the user interaton.

Hope it suits you well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.