15

I am trying to copy one array to another and use this like the new array without any changes to old one:

<div id="app">
    <div class="form-group">
       <label>Test input</label>
       <input v-model="testArray[0].name" type="text" class="form-control" placeholder="Input">
    </div>
    <br>
    <pre>testArray: {{ testArray[0] | json}}</pre>
    <pre>templateArray: {{ templateArray[0] | json  }}</pre>

new Vue({
  el: '#app',
  data: {
      testArray: [],
      templateArray: [{name: "TEST"},], 
  },
  ready: function() {
      this.testArray = this.templateArray.slice(0);
    },
});

the issue is that then I am updating new array 'testArray' I also change old array 'templateArray'.

The script in action: https://jsfiddle.net/4po1cpkp/7/

Is there any way to create new array based on array template without directly binding it to template?

4 Answers 4

24

As Vue.js documentation says:

Under the hood, Vue.js attaches a hidden property __ob__ and recursively converts the object’s enumerable properties into getters and setters to enable dependency collection. Properties with keys that starts with $ or _ are skipped.

You can store your template array with name started from underscore sign:

  data: {
      testArray: [],
      _templateArray: [{ name: "TEST" }]
  },
  ready: function() {
      this.testArray = this.$data._templateArray;
  }

Or you if need it as a Vue.js object:

this.testArray = JSON.parse(JSON.stringify(this.templateArray));

The second case might be slow for big data.

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

Comments

0

I used Vue extend function Vue.util.extend to copy array with un-binding in Vue 2:

this.items_list.push(Vue.util.extend({}, this.list_item));

Comments

0

OPTION 1

You should assign data to testArray by using JavaScript concat() function to copy old array to new array like this one, use this if you work with small array data:

this.testArray = [].concat(this.templateArray);

OPTION 2

You can use ES6 spread operator to merge multiple array like this:

this.testArray = [...[],...this.templateArray]

OPTION 3 ( For big data )

const MAX_BLOCK_SIZE = 65535; // max parameter array size for use in Webkit
export function appendArrayInPlace(dest: [], source: []) {
    let offset = 0;
    let itemsLeft = source.length;

    if (itemsLeft <= MAX_BLOCK_SIZE) {
        dest.push.apply(dest, source);
    } else {
        while (itemsLeft > 0) {
            const pushCount = Math.min(MAX_BLOCK_SIZE, itemsLeft);
            const subSource = source.slice(offset, offset + pushCount);
            dest.push.apply(dest, subSource);
            itemsLeft -= pushCount;
            offset += pushCount;
        }
    }
    return dest;
}

OPTION 3 CREDIT TO enter link description here

Comments

-2

You can use slice() of array prototype read more in MDN Array.prototype.slice()

this.testArray = [].slice.call(this.templateArray)

2 Comments

this.testArray = this.templateArray.slice() seems to do the exact same thing.
If it's the same as slice() it doesn't work for what the OP asked. It'll continue to be deeply attached to the original array, as mentioned in the question.

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.