24

In Vue2, 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://v2.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?

8
  • What do you mean by update? add item, replace item or delete item? Commented Aug 17, 2017 at 9:02
  • I mean replace all items with a new array Commented Aug 17, 2017 at 9:11
  • 2
    So why not just replace it like oldArr = newArr? Commented Aug 17, 2017 at 9:15
  • 1
    But what happens when you try it? (Assigning the entire array is not one of the caveats) Commented Aug 17, 2017 at 10:50
  • 1
    It's a valid question that could be useful for future reference. You can write up your own answer to make it complete. Commented Aug 17, 2017 at 11:36

5 Answers 5

22

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

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

2 Comments

it doesn't call component update for children's, in case I pass array as prop
This appears to have worked in Vue 2.6, but doesn't work with Vue 2.7. Just dealing with a bug migrating to 2.7 and array assignment ends up creating a non-reactive array. Using push still works though.
4

i just use

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

read about it here

Comments

2

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

oldArr.length = 0
oldArr.concat(newArr)

Comments

1

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://v2.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://v2.vuejs.org/v2/guide/list.html#Replacing-an-Array

Comments

1

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://v2.vuejs.org/v2/guide/list.html#Mutation-Methods

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.