Jorje12
Jorje12

Reputation: 423

Does Spread syntax make Vue detect changes in arrays?

Vue documentation states:

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

But I couldn't find anything about spread operators.

Will Vue detect a change if we use this.arr1 = [...arr2, ...arr3]; for arr1, where arr1 is declared in data({})?

spread operators do make a lot of things easier, but are they safe in this context ?

Upvotes: 1

Views: 1659

Answers (2)

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

Yes this is safe, practical and reactive in case of pushing data, concatenating ... :

let app = new Vue({

  el: '#app',

  data() {
    return {
      arr1: [1, 2, 3],
      arr2: [4, 5, 6],
      arr3: []
    }
  },
  methods: {
    fillArray() {
      this.arr3 = [...this.arr1, ...this.arr2]
    },
    random() {
      this.arr3 = [...this.arr3, Number(Math.random() * 100).toFixed()]
    },
    updateFirstIndex() {
      this.arr3[0] = 44;
      console.log(this.arr3);
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <button @click="fillArray">
    fill array
</button>
  <button @click="random">
    Add random value
</button>
<br>
Not reactive if you update a given element at some index :

  <button @click="updateFirstIndex">
  update First Index
</button>
  <pre>
{{arr3}}
</pre>
</div>

Upvotes: 2

Phil
Phil

Reputation: 164892

When you assign a new value to a reactive property, it is still reactive.

It doesn't matter so much how you construct the new value, it's the assignment that counts.

Even though Vue offers several helpful extensions to array mutation (push and splice), one of the better paths to take is to treat all reactive properties as immutable; that is, never make direct changes, always assign a new value.

Bad (not reactive)

this.arr[0].objectProperty = 'new value'
this.arr[0] = { 'new': 'value' }
this.arr.length = 0

Ok (supported by Vue)

this.arr.push({ 'new': 'value' })
this.arr.splice(0, 1)

Good (Immutable)

this.arr = this.arr.filter(...)
this.arr = this.arr.concat(...)
this.arr = [...arr2, ...arr3]

This is a React focused article but the concepts are the same for Vue (and pretty much anything with a Virtual DOM)

Immutability in React: There’s nothing wrong with mutating objects

Upvotes: 2

Related Questions