Vue.js is a reactive framework. Anything that’s being bind to the app state will re-render the view whenever there’s an update to it’s content. However, this doesn’t work if the record is an object or list of objects and something within the object changes. Vue is unable to watch changes make deeply nested in an object or array of objects. In such cases, you might need to do something to force-update the view. Consider this example, where I have an object name person. Whenever I add or update any property to the object, the view wouldn’t re-render:
<template>
<div id="app">
<button @click="addProperties">Add new properties</button>
<div v-for="(value, i) in person" :key="i">
{{ value }}
</div>
<div class="np-credits">wwww.nightprogrammer.com</div>
</div>
</template>
<script>
import Vue from "vue";
export default {
name: "App",
data() {
return {
person: {
name: "Gautam",
},
};
},
methods: {
addProperties() {
this.person.age = 27;
},
},
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding: 24px;
}
button {
background-color: #004cbe;
color: #ffffff;
border: 0px;
border-radius: 6px;
padding: 6px 20px;
margin-right: 1em;
cursor: pointer;
transition: all 0.3s;
margin-bottom: 8px;
}
button:hover {
background-color: #2f79e7;
transition: all 0.3s;
}
.np-credits {
font-size: 12px;
margin-top: 12px;
color: #4b4b4b;
}
</style>
Code language: HTML, XML (xml)
In the above example, I’m calling a method called addProperties. Then adding a key named age with a value of 27. This object is actually updated but, that isn’t reflected in the view. There are multiple ways to fix that:
- Vue.set()
- this.$set
- Object.assign()
- Spread operator (…)
You can use the Vue.set() method as follows to update the object instantly:
addProperties() {
Vue.set(this.person, "age", 27);
},
Code language: JavaScript (javascript)
Or, you could use the this.$set method to update the state and reflect the change as well. It’s worth noting that this in this context refers to the component scope in the application. Which also inherits the Vue instance scope directly.
addProperties() {
this.$set(this.person, "age", 27);
},
Code language: JavaScript (javascript)
You could also use the Object.assign() method to add or update multiple values to the object directly:
addProperties() {
this.person = Object.assign({}, this.person, {
age: 27,
nationality: "Indian",
});
},
Code language: JavaScript (javascript)
Using the JavaScript spread operator is yet another way to achieve the desired result:
this.person = { ...this.person, nationality: "Indian" };
Code language: JavaScript (javascript)
Personally, I love using the spread operator for this task.
You can find a working demo of the above example from my repo links below. If you have any doubts / suggestions, let me know in the comment section below!