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.