A Guide To Vue Lifecycle Hooks

A simple introduction to the lifecycle hooks and when to use them.

Matt Maribojoc
Dec 15, 2019 · 5 min read

VueJS Lifecycle Hooks seem like a pretty easy concept, and they are! But making sure you’re putting code in the optimal hook takes a little bit of thought sometimes.

I know that for a while, I use to just throw almost all of my initialization code in the mounted method (bad!), so hopefully I can prevent some fellow developers from making the same mistakes.

First let’s look at a diagram of the lifecycle hooks from the official Vue documentation. This should give a decently high level overview of what’s going on before we can dive down into the details.

From https://vuejs.org/v2/guide

Essentially, each main lifecycle event is separated into two hook that is called right before that event and then right after. There are four main events (8 main hooks) that you can utilize in your Vue app.

  • Creation — runs on your component’s creation
  • Mounting — runs when the DOM is mounted
  • Updates — runs when reactive data is modified
  • Destruction — runs right before your element is destroyed.

Let’s go into a little more depth.

Creation Hooks

Creation hooks are the very first thing that runs in your program.

beforeCreate()

Since the created hook is the thing that initializes all of the reactive data and events , beforeCreate does not have access to any of a component’s reactive data and events.

Take the following code block for example:

<script> 
export default {
data() {
return {
val: 'hello'
}
},
beforeCreate() {
console.log('Value of val is: ' + this.val)
}
}
</script>

The output would be value of val is undefined because data has not been initialized yet. You also cannot call your component methods in this method either.

If you want to see a full list of what is available, I’d recommend just running console.log(this) to see what has been initialized. This is useful in every other hook too.

Using the beforeCreate hook is useful when you need some sort of logic/API call that does not need to be assigned to data. Because if we were to assign something to data now, it would be lost once the state was initialized.

created()

We now have access to the component’s data and events. So modifying the example from above to use created instead beforeCreate we see how the output changes.

<script> 
export default {
data() {
return {
val: 'hello'
}
},
created() {
console.log('Value of val is: ' + this.val)
}
}
</script>

The output of this would be Value of val is: hello because we have initialized our data.

Using the created method is useful when dealing with reading/writing the reactive data. For example, if you want to make an API call and then store that value, this is the place to do it. It’s better to do that here than in mounted because it happens earlier in Vue’s synchronous initialization process and you perform data reading/writing all you want.

Mounting Hooks

These mounting hooks handle mounting and rendering the component. These are some of the most commonly used hooks in projects and applications.

beforeMount()

Called right before the component DOM is actually rendered and mounted. In this step, this.$el does not exist yet.

<script> 
export default {
beforeMount() {
console.log(this.$el)
}
}
</script>

Output: undefined

While it’s preferred that you use created() to perform your API calls, this is really the last step you can call them before it’s unnecessary late in the process because it’s right after created — they have access to the same component variables.

mounted()

Called right after the first render of the component. this.$el is now available allowing for direct DOM access.

One thing to note is that while this is called after this component is mounted, there is no guarantee that all of the child components are mounted. If you need to access child components, you can make sure that they are available by wrapping the code inside your mounted method in a this.$nextTick() which will run after all your code has been rendered. Note that this uses an arrow function to preserve this.

<script> 
export default {
mounted() {
this.$nextTick(() => {
// all child components are rendered and ready
}
}
}
</script>

Update Hooks

The updated lifecycle event is triggered whenever reactive data is modified, triggering a render update.

beforeUpdate()

Runs before the data is changed and the component is re-rendered. So all of the data values in this method will be the pre-change values.

updated()

Again, similar to mounted , it’s not guaranteed that all of the child components have been updated. So if you need that, just use the nextTick() method similar to before.

To see the difference between beforeUpdate() and updated() let’s use the following template code.

<template>
<div>
<p>{{val}}</p>
<button @click='val = 5'>Click to Change</button>
</div>
</template>

With this corresponding script.

<script> 
export default {
data() {
return {
val: 0
}
},
beforeUpdate() {
console.log("beforeUpdate() val: " + this.val)
},
updated() {
console.log("updated() val: " + this.val
}
}
</script>

The output would be.

beforeUpdate() val: 0
updated() val: 5

This methods are useful, but for a lot of use cases we may want to consider using watchers or computed values to change the state based on elements.

Destruction Hooks

The destruction hooks for a component are used in the process of removing a component and cleaning up all the loose ends. This is the time for removing event listeners and things that could lead to memory leaks if not properly processed.

beforeDestroy()

Because this is before the component starts to get torn down, this is the time to do most, if not all, of the clean up. At this stage, your component is still fully functional and nothing has been destroyed yet.

An example of cleaning up an event listener would look like this.

<script>
export default {
mounted() {
this.someMethod();
window.addEventListener('resize', this.someMethod);
},
beforeDestroy() {
window.removeEventListener('resize', this.someMethod);
},
methods: {
someMethod() {
// do smth
}
}
}
</script>

destroyed()

At this point, most of your component and properties is gone so there’s not much you can do. Once again, I’d use console.log(this) to see what exactly is still around and if it could be useful for your project.

That’s It.

Hopefully this was a useful quick little overview of VueJS Lifecycle Hooks and which one to use in your projects.

If you have any questions, let me know in the responses or find me on Twitter!


If you’re looking to power up your Vue development, I’ve created a 3 page PDF cheatsheet with all of the essential references that every Vue developer needs. It’s saved me so much time and thousands of the same Google searches.

JavaScript in Plain English

Learn the web's most important programming language.

Matt Maribojoc

Written by

I run a VueJS community over at https://learnvue.co, develop web sites, and post whatever I find cool on the Internet.

JavaScript in Plain English

Learn the web's most important programming language.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade