Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue change object in array and trigger reactivity

How can I trigger an update when altering part of an object found by index in an array?

The docs show how to alter the value of an array:

Vue.set(example1.items, indexOfItem, newValue) 

or

example1.items.splice(indexOfItem, 1, newValue) 

But how to alter the value of a property on an object in an array without changing the rest of the object?

The following works to update the property, but Vue doesn't react to the change until something else triggers an update.

example1.items[indexOfItem].some_object_property = false 
like image 996
shanemgrey Avatar asked Oct 28 '17 00:10

shanemgrey


People also ask

What does $Set do in Vue?

js $set() method to set data object properties. Binding a class on an item and controlling it by the truthy value of a data property is a powerful feature of Vue.

How does reactivity work in Vue?

Vue's reactivity system works by deeply converting plain JavaScript objects into reactive proxies. The deep conversion can be unnecessary or sometimes unwanted when integrating with external state management systems (e.g. if an external solution also uses Proxies).

Are Props reactive Vue?

Props and data are both reactiveWith Vue you don't need to think all that much about when the component will update itself and render new changes to the screen. This is because Vue is reactive. Instead of calling setState every time you want to change something, you just change the thing!


1 Answers

You could update the sub-property in the array element with this.$set(). For example, to increment an x subproperty in the first two array elements (creating the sub-property if it doesn't exist):

methods: {   update() {     this.$set(this.arr[0].foo, 'x', (this.arr[0].foo.x || 0) + 100)     this.$set(this.arr[1].foo, 'x', (this.arr[1].foo.x || 0) + 100)   } } 

new Vue({   el: '#app',   data() {     return {       arr: [         {           foo: {             x: 100,             y: 200           }         },         {           foo: {             /* x does not exist here initially */             y: 400           }         }       ]     };   },    methods: {     update() {       this.$set(this.arr[0].foo, 'x', (this.arr[0].foo.x || 0) + 100)       this.$set(this.arr[1].foo, 'x', (this.arr[1].foo.x || 0) + 100)     }   } })
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>  <div id="app">   <button @click="update">Update</button>   <p>arr[0]: {{ arr[0] }}</p>   <p>arr[1]: {{ arr[1] }}</p> </div>

codepen

like image 134
tony19 Avatar answered Nov 15 '22 16:11

tony19