VueJs lifecycle hooks – what, why and how

2022.02.07

Introduction

Every VueJs application has an instance that goes through series of steps that are part of its lifecycle. VueJs provides hooks which are methods where you can perform actions before or after those steps have been executed giving you flexibility allowing control those behaviors. This article will explain most important hooks and how we can use them to gain control over components.

VueJs Instance

An VueJs application begins with what's called Vue instance. Evey instance has its root Vue instance and optional tree of components. When we initialize a Vue instance, we usually pass data object, then Vue takes those properties and injects then into its reactivity system. Properties added at this stage will trigger re-rendering changes of a component, properties added after the instance has been initialized will not.

In example below, if property "a" changes, the component will re-render, while the property "b" will not trigger that behavior.

let vm = new Vue({
    data: {
        a: 1
    }
})

vm.b = 2

Lifecycle of an Instance

Every instance since initialization goes through a series of steps, setup data for observation, mount the instance on the DOM, update DOM when data changes etc. The complete process is illustrated below.

First available are the creation hooks. At this point you can implement logic that will be run before the component has been added to the DOM. In this phase you will not have access to the DOM. In beforeCreate hook you cannot access methods or data, those become available in created hook. The created hook also should be used to fetch data for component initialization.

Next come mounting hooks. During this steps the initial render is performed and hooks allow you to access and modify the DOM before and after the render. This phase is also suitable for initializing 3rd party libraries to be included into the components. Check this article for using VueJs with DiagramMaker library.

Updating hooks take care of reactive properties of the component. You can control data before it is updated and after. There is a common mistake of using those hooks to check if data of the component has changed, for this task 'watchers' should be used.

Lastly, destroy hooks are used for clean up actions like removing instances of 3rd party libraries or analytics.

<template>
  <div class='my-component'>
    <div>Count: {{count}}</div>
    <button @click="updateCount">Update</button>
  </div>
</template>

<script>

export default {
  name: 'LifecycleHooks',
  data () {
    return {
      count: 0,
      thirdPartyInstance: null
    }
  },
  methods: {
    fetchData () {
      this.count = 22
    },
    updateCount () {
      this.count += 1
    }
  },
  beforeCreate () {
    console.log('I cannot access data or methods yet')
  },
  created () {
    console.log('The count is ' + this.count)
    this.fetchData()
    console.log('The count after fetch is ' + this.count)
  },
  beforeMount () {
    this.thirdPartyInstance = new Date()
  },
  mounted () {
    console.log('mounted ', this.$el.textContent)
  },
  beforeUpdate () {
    console.log('beforeUpdate: ', this.count)
    console.log('beforeUpdate: ', this.$el.textContent)
  },
  updated () {
    console.log('updated ', this.$el.textContent)
  },
  beforeDestroy () {
    console.log('beforeDestroy', this.thirdPartyInstance)
    delete this.thirdPartyInstance
  },
  destroyed () {
    console.log('Watchers, children and event listeners have been removed')
  }
}
</script>
I cannot access data or methods yet
The count is 0
The count after fetch is 22
mounted  Count: 22 Update
beforeUpdate:  23
beforeUpdate:  Count: 22 Update
updated  Count: 23 Update
beforeDestroy Mon Feb 07 2622 14:00:00 GMT+0900 (Japan Standard Time)
Watchers, children and event listeners have been removed

Notice how in beforeUpdate, first line logged returns 23 meaning data of the component has been updated but second says Count: 22. This is because DOM has not been re-rendered yet.

Conclusion

We discovered lifecycles which are steps through which every VueJs application and its components go through. Vuejs provides hooks to control the behavior before and after those steps.