Vue 3 Component Lifecycle Hooks Explained

Every Vue component follows a predictable sequence of initialization, rendering, patching, and teardown. During each phase Vue exposes dedicated hooks so you can run custom logic at the exact moment you need.

Declaring Hooks

Hooks are plain instance methods. The framework invokes them automatically; you only need to provide the body.

import { defineComponent } from 'vue'

export default defineComponent({
  mounted() {
    console.log('DOM is ready')
  }
})

Inside every hook the runtime binds this to the current component instance. Do not use arrow functions, because they preserve the outer lexical scope and you will lose access to the component.

Lifecycle Overview

Hook Details

beforeCreate

Useful for global configuration that must run before any reactivity is installed.

beforeCreate() {
  console.log('No data, no watchers yet')
}

created

Perfect for fetching initial data or setting up non-reactive state.

async created() {
  this.posts = await api.fetchPosts()
}

beforeMount

Rarely needed; sometimes used to tweak the render function just before the first paint.

beforeMount() {
  console.log('About to render for the first time')
}

mounted

Ideal for third-party libraries that require real DOM nodes, such as charts or map widgets.

mounted() {
  this.chart = new Chart(this.$refs.canvas, this.chartConfig)
}

beforeUpdate

Access the pre-patch DOM state; useful for manual diffing or measuring layout.

beforeUpdate() {
  this.scrollTop = this.$refs.list.scrollTop
}

updated

React to DOM changes; avoid mutating reactive data here to prevent infinite loops.

updated() {
  this.$nextTick(() => this.$refs.input.focus())
}

beforeUnmount

Clean up timers, cancel network requests, or remove global event listeners.

beforeUnmount() {
  clearInterval(this.timerId)
}

unmounted

Perform final teardown; the component instance is no longer usable.

unmounted() {
  console.log('Component is gone')
}

Complete Example

<template>
  <div>
    <p>{{ counter }}</p>
    <button @click="counter++">+</button>
  </div>
</template>

<script>
import { defineComponent } from 'vue'

export default defineComponent({
  name: 'LifecycleLogger',
  data() {
    return { counter: 0 }
  },
  beforeCreate()  { console.log('beforeCreate')  },
  created()       { console.log('created')       },
  beforeMount()   { console.log('beforeMount')   },
  mounted()       { console.log('mounted')       },
  beforeUpdate()  { console.log('beforeUpdate')  },
  updated()       { console.log('updated')       },
  beforeUnmount() { console.log('beforeUnmount') },
  unmounted()     { console.log('unmounted')     }
})
</script>

Mounting and then incrementing the counter will print the hooks in the exact order listed above.

Tags: vue3 lifecycle hooks component lifecycle frontend framework javascript

Posted on Sun, 17 May 2026 03:35:08 +0000 by Sa177ir