I recently encountered an error on the render of one of my Vue component. I was not aware that if you declare an object
into data
in VueJs, if you modify it by adding or deleting properties that are not declared at the beginning as nested properties, VueJS will not dynamically listen to the change, though will not re render your component.
To avoid this behavior, when you add or remove properties in a object that were not previously declared, VueJS has a dedicated method for it.
Uou have a car object declared in your component :
<html> <div id="root"> <h1>{{ car.model }}</h1> <p>This car is a {{car.white}}{{car.brand}}</p> <button @click="showWheels" >How many wheels ?</button> <p v-if="car.wheels">{{car.wheels}}</p> </div> </html> <script> const app = new Vue({ el: '#root', data: { car: { model: 'XYZ', color: 'white', brand: 'Toyota', } }, methods: { showWheels(){ this.car.wheels = 4; // this will add wheels attribute to car object, but will not re render the view, so user will not see the change this.$set(this.car, 'wheels', 4); // this will add wheels attribute to car object, but will subscribe this attribute and re render the view, user will see change. } } }); </script>
On previous example, if we wanted to use this.car.wheels = 4
, we should have done :
<script> const app = new Vue({ el: '#root', data: { car: { model: 'XYZ', color: 'white', brand: 'Toyota', wheels: 0 } }, methods: { showWheels(){ this.car.wheels = 4; // this time the view will re-render due to wheels declaration in data } } }); </script>
For object deletion, in order to keep VueJS reactivity, we use :
delete car.wheels //Will not re render if wheels not declared this.$delete(this.car, 'wheels') //Will delete attribute and add VueJS reactivity
So be careful on how you declare object in data, they can loose reactivity if properties are not defined as well !
If you want to know more about this concept you can check this official documentation