Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Vue.js have a built in way to add a copy of a persistent object to a repeated array

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.

like image 883
DutGRIFF Avatar asked Jun 01 '15 16:06

DutGRIFF


People also ask

What feature of Vue can be used to repeat an element using a collection of data?

You can use the v-repeat directive to repeat a template element based on an Array of objects on the ViewModel.

How do you make a deep copy in JavaScript?

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.


2 Answers

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.

like image 87
DutGRIFF Avatar answered Sep 29 '22 18:09

DutGRIFF


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 ) ) ); 
like image 42
user3698965 Avatar answered Sep 29 '22 20:09

user3698965