Vue 3 Options API – Lifecycle Hooks
Lifecycle hooks are top-level options on the component object. this inside
each hook is the component instance.
Order (one mount/update/unmount cycle)
beforeCreate
created ← reactive data ready, DOM not yet
beforeMount
mounted ← DOM ready, child components mounted
beforeUpdate
updated ← reactive change re-rendered
beforeUnmount
unmounted ← clean up here
Common patterns
Fetch on mount
export default {
data() {
return { user: null, loading: true }
},
async mounted() {
try {
this.user = await api.get('/me')
} finally {
this.loading = false
}
},
}
Prefer
mounted()for fetches that need DOM (e.g. focus management) andcreated()for fetches that don't (it fires earlier so data is available sooner during SSR).
Set up listeners — always tear down
export default {
mounted() {
window.addEventListener('resize', this.onResize)
},
beforeUnmount() {
window.removeEventListener('resize', this.onResize)
},
methods: {
onResize() { /* ... */ },
},
}
If you forget beforeUnmount, listeners leak and you get duplicated handlers
across hot reloads.
Timers / intervals
data() {
return { timer: null, ticks: 0 }
},
mounted() {
this.timer = setInterval(() => this.ticks++, 1000)
},
beforeUnmount() {
clearInterval(this.timer)
},
Activated / deactivated
These fire when the component is wrapped in <KeepAlive>. Don't use them
unless the component is actually inside <KeepAlive> — they won't fire
otherwise.
Async hooks
All hooks can be async:
async created() {
this.config = await loadConfig()
}
Vue does not wait for the promise — the rest of the lifecycle continues.
Use loading flags in your template if you depend on the result.
errorCaptured
errorCaptured(err, instance, info) {
console.error('child error:', err, info)
this.error = err.message
return false // stop propagation
}
Useful for error boundaries around a subtree.