Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.
In this article, we’ll look at the lifecycle hooks of a Vue instance.
Vue Instance Lifecycle Hooks
Each Vue instance goes through a lifecycle. The lifecycle events can be handled with functions, which are the lifecycle hooks.
For example, when a Vue instance is created, the created
hook is called.
We can handle the created
event emitted by Vue.js as follows:
new Vue({
data: {
foo: "bar"
},
created() {
console.log(`foo is ${this.foo}\`);
}
});
Then we should see foo is bar
from the console.log
. Once the Vue instance is created and the initial data is set, the created
hook is called.
This is why we see such output from the console.log
.
Note that we can’t use arrow functions for lifecycle hooks since we reference the properties from this
, which is the Vue instance.
There’re also other lifecycle hooks like mounted
, updated
, destroyed
.
Lifecycle Diagram
The full lifecycle diagram is below. It outlines the whole workflow for creating a new Vue instance.
The red rounded rectangles have the hooks that are called.
Courtesy of vuejs.org
Creation Hooks
Creation hooks are called when the Vue instance begins its initialization process. It lets us do things before the Vue instance is added to the DOM.
This hook is also run during server-side rendering
We don’t have access to this.$el
(the target mounting element) or the DOM within this hook since no DOM manipulation is done at this point.
beforeCreate
The beforeCreate
hook runs during initialization. data
has been made reactive and events
aren’t set up yet.
For example, if we have:
new Vue({
data: {
foo: "bar"
},
beforeCreate() {
console.log("beforeCreated called");
},
created() {
console.log(`foo is ${this.foo}`);
}
});
Then we see:
beforeCreated called
foo is bar
which confirms that beforeCreate
is called before created
.
created
data
and events
are available in the created
hook since the Vue instance has been initialized.
For example, if we write:
new Vue({
data: {
foo: "bar"
},
created() {
this.foo = "baz";
console.log(`foo is ${this.foo}`);
}
});
Then we get:
foo is baz
since we changed the value of this.foo
in the created
hook before logging its value.
Mounting Hooks
The mounting hooks are run when DOM manipulation is being done, including mounting the Vue instance to the specified element.
We can use it to access or modify the DOM of our component.
beforeMount
The beforeMount
hook runs before the initial render happens and after the template or render functions are compiled.
It doesn’t get called during server-side rendering.
For instance, if we write:
new Vue({
el: "#app",
data: {
foo: "bar"
},
created() {
console.log(`created called`);
},
beforeMount() {
console.log(`beforeMount called`);
}
});
Then we get:
created called
beforeMount called
mounted
When the mounted
hook is called, we have access to the component, template, and the DOM.
It’s used frequently for the initialization of our own data like fetching data over the network and integrate non-Vue libraries.
For example, if we have the following in src/index.js
:
new Vue({
el: "#app",
data: {
foo: "bar"
},
beforeMount() {
console.log(this.$el.textContent);
}
});
and the following in index.html
:
<!DOCTYPE html>
<html>
<head>
<title>Hello</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">foo</div>
<script src="./src/index.js"></script>
</body>
</html>
Then we get foo
logged since we have foo
in the div
with ID app
.
Updating Hooks
Updating hooks are called when a reactive property used by our component changes or we some triggers re-rendering manually.
They’re useful for checking when a component is re-rendering.
However, we should use computed properties or watchers to track reactive property changes.
beforeUpdate
beforeUpdate
runs after data changes in our component, right before the DOM is updated and re-rendered.
It lets us get the new state before the DOM is re-rendered.
For example, if we have the following in src/index.html
:
new Vue({
el: "#app",
data: {
foo: "bar"
},
beforeUpdate() {
console.log(this.foo);
},
methods: {
toggle() {
this.foo = this.foo === "bar" ? "baz" : "bar";
}
}
});
and the following in index.html
:
<!DOCTYPE html>
<html>
<head>
<title>Hello</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<p>{{foo}}</p>
<button @click="toggle">Toggle</button>
</div>
<script src="./src/index.js"></script>
</body>
</html>
Then when we click the Toggle button, we can see the value changes logged in the console.log
call of the beforeUpdate
method.
updated
The updated
hook runs after data changes on our Vue instance and the DOM re-renders.
For example, if we have the following in src/index.js
:
new Vue({
el: "#app",
data: {
foo: "bar"
},
updated() {
console.log(this.$refs.foo.textContent);
},
methods: {
toggle() {
this.foo = this.foo === "bar" ? "baz" : "bar";
}
}
});
and the following in index.html
:
<!DOCTYPE html>
<html>
<head>
<title>Hello</title>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head> <body>
<div id="app">
<p ref="foo">{{foo}}</p>
<button @click="toggle">Toggle</button>
</div>
<script src="./src/index.js"></script>
</body>
</html>
Then we can get the text content of the p
element with ref
set to foo
by logging the value as follows:
console.log(this.$refs.foo.textContent);
in the updated
hook and we can see the new value for it as we click the Toggle button.
Destruction Hooks
These hooks are run when the Vue instance is destroyed. Therefore, we can run clean up code in there.
These hooks aren’t run during server-side rendering.
beforeDestroy
beforeDestroy
is run before teardown. Our Vue instance is still present and functional.
Therefore, we can run our clean up code in here.
For example, we can use it as follows:
new Vue({
el: "#app",
data: {
foo: "bar"
},
beforeDestroy() {
this.foo = null;
}
});
destroyed
This is called after the Vue instance is destroyed. All the directives are unbound, event listeners are removed and child Vue instances are destroyed.
For example, we can use it as follows:
new Vue({
el: "#app",
data: {
foo: "bar"
},
destroyed() {
this.foo = null;
}
});
Conclusion
The lifecycle hooks are useful for doing things during the lifecycle of the Vue instance.
The creation hooks can be used to run any initialization code.
The mounting hooks are run when the Vue instance is being mounted into the DOM.
The update hooks whenever data of the Vue instance updates, and the destroy hooks are run when the Vue instance is being destroyed.