'vue.js best way to update entire array

What is the best way to update the entire observed array and trigger a rerender in vue.js without having to iterate an push all the items?

I have read the documentation here: https://vuejs.org/v2/guide/list.html#Replacing-an-Array

But it doesn't make sense to me having to filter, concat or slice just to update the array? There must be something I missed?



Solution 1:[1]

As suggested I will repond to this myself to help anyone in the same predicament.

oldArr = newArr

should still work (thank you choasia. Even though it is somewhat unclear in the vue.js documentation. Replacing the entire array will not fall under the caveats mentioned there (thank you Roy J ).

One option might also be to to empty the array and then push the new one like:

yourArray.push(... yourNewArray)

Thank you reiner

Solution 2:[2]

i just use

this.myArray = this.myArray.slice();

read about it here

Solution 3:[3]

I ran into this as well, and a lot of sample code out there from Vue 1.0 gives incorrect information on this topic. So I thought it might be helpful to post my findings in followup to Janspeed's correct answer on this topic.

For example, given an array defined in the data: block as follows:

  data: {
    event: { name: '', description: '', date: '' },
    events: []
  }

To set the entire array (in these examples, to the a local array var localEvents), these both work just fine, and you have a bit more flexibility with the second method:

this.events = localEvents; // assigns array, is reactive
this.events = localEvents.slice(0, localEvents.length); // assigns array, is reactive

You will see samples like this in tutorials, it doesn't work:

this.set$("events", localEvents)

It will result in this error:

Cannot set reactive property on undefined, null, or primitive value: events

Per: https://vuejs.org/v2/guide/migration.html#Array-prototype-set-removed

However, Vue.set can be used to reactively add elements to an array. Therefore, given an array with length 3:

Vue.set(this.events, 4, newEvent); // adds newEvent to array reactively
this.events.splice(4, 1, newEvent); // also adds newEvent to array reactively

Of course, per the examples in the documentation, if you specify an index value corresponding to a existing array element, it will be replaced by your input object (newEvent in the examples above).

See: https://vuejs.org/v2/guide/list.html#Replacing-an-Array

Solution 4:[4]

If you want to replace an entire array and create a new reactive array, the easiest way is to use one of the supported array manipulation methods which are eg. .concat():

this.newArray = this.oldArray.concat()

Using this.newArray = this.oldArray will clone reactivity from one array to another, so changes to this.oldArray will also be reflected on this.newArray which is usually not a behaviour you want to achieve.

You can also check other supported array manipulation methods in Vue docs: https://vuejs.org/v2/guide/list.html#Mutation-Methods

Solution 5:[5]

Set the initial arrays length to 0 and then merge them together:

oldArr.length = 0
oldArr.concat(newArr)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Janspeed
Solution 2 Dan Levin
Solution 3 Shane K
Solution 4 Dawid Stefaniak
Solution 5 urbz