I have a Vue.js app where I have a v-repeat on an array of items. I want to add a newItem to the list of items. When I try this.items.push(this.newItem)
the object pushed is still bound to the input. Consider the below:
new Vue({ el: '#demo', data: { items: [ { start: '12:15', end: '13:15', name: 'Whatch Vue.js Laracast', description: 'Watched the Laracast series on Vue.js', tags: ['learning', 'Vue.js', 'Laracast', 'PHP'], note: "Vue.js is really awesome. Thanks Evan You!!!" }, { start: '13:15', end: '13:30', name: "Rubik's Cube", description: "Play with my Rubik's Cube", tags: ['Logic', 'Puzzle', "Rubik's Cube"], note: "Learned a new algorithm." } ], newItem: {start: '', end: '', name: '', description: '', tags: '', note: ''} }, methods: { addItem: function(e) { e.preventDefault(); this.items.push(this.newItem); } } });
The above will, as expected, push the object that is bound onto the items array. The problem is I want just a copy of the object so it will no longer change when the input changes. See this this fiddle. I know I can do:
addItem: function(e) { e.preventDefault(); this.items.push({ name: this.newItem.name, start: this.newItem.start, end: this.newItem.end, description: this.newItem.description, tags: this.newItem.tags, notes: this.newItem.notes }) }
This works but is a lot of repetition.
The question: Is there a built in way to add just a copy of the object instead of the persistent object.
You can use the v-repeat directive to repeat a template element based on an Array of objects on the ViewModel.
Copy an Object With Object. assign() was the most popular way to deep copy an object. Object. assign() will copy everything into the new object, including any functions. Mutating the copied object also doesn't affect the original object.
See this issue on GitHub.
Shallow Clone
I was using jQuery's $.extend
until Evan You pointed out there is an undocumented built it extend function Vue.util.extend
that does a shallow clone. So what you could use is:
addItem: function(e) { e.preventDefault(); this.items.push(Vue.util.extend({}, this.newItem)); }
See the updated Fiddle.
Deep Clone
When doing a shallow clone on an object that references other objects you copy the references to the external objects instead of cloning them. To clone the object completely do a Deep Clone.
For the deep clone, per Evan's suggestion in the first link, one could use: JSON.parse(JSON.stringify(object))
. This can be seen between this fiddle and this fiddle.
If using lodash check out lodash cloneDeep. If using NPM check out clone-deep.
This didn't work for me (vue 1.0.13). I used the following to create a copy without the data bindings:
this.items.push( JSON.parse( JSON.stringify( newItem ) ) );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With