16

I'm a bit new to JS and Vue and am not quite sure if I understood the documentation correctly. It says:

Due to the limitations of modern JavaScript (and the abandonment of Object.observe), Vue cannot detect property addition or deletion. Since Vue performs the getter/setter conversion process during instance initialization, a property must be present in the data object in order for Vue to convert it and make it reactive.

Does this include normal arrays as well, or do elements in arrays not count as "properties" in JavaScript? I wish to do state.array.push(data) to an array. Is this the correct way to do it?

zcoop98
  • 2,590
  • 1
  • 18
  • 31
fogx
  • 1,749
  • 2
  • 16
  • 38

2 Answers2

34

This is covered in good detail in the Change Detection Caveats section of the docs. For Arrays specifically:

Due to limitations in JavaScript, ... Vue cannot detect the following changes to an array:

  1. When you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue
  2. When you modify the length of the array, e.g. vm.items.length = newLength

The specifics of Array prototype methods are also covered under the list rendering section:

Vue wraps an observed array’s mutation methods so they will also trigger view updates. The wrapped methods are:

  1. push()
  2. pop()
  3. shift()
  4. unshift()
  5. splice()
  6. sort()
  7. reverse()

So the answer to the question is state.array.push reactive? is yes.


Note, however, that the above caveats only apply to Vue 2.

Vue 3 brought a complete overhaul to the reactivity mechanism, switching from using object getters and setters to using an ES6 JavaScript feature called Proxy.

This allows more comprehensive object change monitoring with less setup and less caveats for the user to worry about.

zcoop98
  • 2,590
  • 1
  • 18
  • 31
Roland
  • 24,554
  • 4
  • 99
  • 97
  • ok great. i wasnt sure if they meant the same push() or some vue specific function (since it uses vue.set for the object properties – fogx Jul 05 '19 at 08:16
  • 1
    @fogx you can re-initialize object without "set", just like `state.obj = { ...state.obj, newProp: 123 }` https://vuex.vuejs.org/guide/mutations.html#mutations-follow-vue-s-reactivity-rules – Andriy Kuba Jul 05 '19 at 08:18
9

state.array.push(data) is correct.

What the documentation says is:

// If initially you have an object like this
state = {
   obj:{
       key1: ["dummy"]
    }
};
// this will be reactive
state.obj.key1.push("dummy2");

// however if you add a new property to the object like this,
// then whatever you do with obj['key2'] will not be reactive
state.obj['key2'] = ["dummy"];
Dan Lee
  • 600
  • 6
  • 10