Lifecycle Hooks
Every Vue component has a lifecycle — it is created, mounted to the DOM, possibly updated many times, and eventually unmounted and destroyed. Lifecycle hooks let you run code at specific moments in this process.
The component lifecycle
Section titled “The component lifecycle”setup() ← script setup runs — refs and computed created ↓onBeforeMount ← just before DOM is created ↓onMounted ← component is in the DOM ✅ safe to access DOM ↓(state changes trigger re-renders) ↓onBeforeUpdate ← just before re-render ↓onUpdated ← after re-render ✅ DOM reflects latest state ↓onBeforeUnmount ← just before component is destroyed ↓onUnmounted ← component is gone from DOM ✅ clean up hereIn practice, onMounted and onUnmounted are the hooks you’ll use most often.
onMounted
Section titled “onMounted”Runs after the component is inserted into the DOM. Use it for anything that requires a real DOM element — focusing an input, measuring an element’s size, initializing a third-party library:
<script setup lang="ts">import { ref, onMounted } from 'vue'
const inputRef = ref<HTMLInputElement | null>(null)
onMounted(() => { inputRef.value?.focus()})</script>
<template> <input ref="inputRef" type="text" placeholder="Search..." /></template>ref="inputRef" is a template ref — it gives you a reference to the actual DOM element. After mounting, inputRef.value is the <input> element.
onUnmounted
Section titled “onUnmounted”Runs when the component is removed from the DOM. Use it to clean up side effects that would otherwise persist — event listeners, timers, subscriptions:
<script setup lang="ts">import { onMounted, onUnmounted } from 'vue'
let intervalId: ReturnType<typeof setInterval>
onMounted(() => { intervalId = setInterval(() => { console.log('tick') }, 1000)})
onUnmounted(() => { clearInterval(intervalId) // clean up the timer})</script>Forgetting to clean up on unmount causes memory leaks — the interval keeps running even after the component is gone.
onBeforeUnmount
Section titled “onBeforeUnmount”Runs just before the component is destroyed. The DOM is still accessible here, which is occasionally useful for saving state before the component disappears.
onUpdated
Section titled “onUpdated”Runs after a reactive change causes a re-render. Use cautiously — it fires on every update, which can be frequent. Often watch or watchEffect is a better choice for reacting to specific data changes.
When you don’t need lifecycle hooks
Section titled “When you don’t need lifecycle hooks”Watchers created with watch and watchEffect in <script setup> are automatically cleaned up on unmount. You don’t need onUnmounted for them.
Side effects triggered by reactive data are often better expressed with watch/watchEffect than lifecycle hooks.
Exercise
Section titled “Exercise”- Create a component with
onMountedthat logs “Component mounted!” to the console. - Add an
onUnmountedthat logs “Component unmounted!”. - Add a
v-iftoggle in a parent component that conditionally renders/destroys your component. Verify both messages appear at the right times. - Use
onMountedto auto-focus a text input using a template ref.
onMountedruns after the component is in the DOM — safe to access DOM elements and template refs.onUnmountedruns when the component is removed — use it to clean up timers, listeners, and subscriptions.onBeforeUnmountruns just before destruction — DOM still accessible.onUpdatedruns after every re-render — usewatch/watchEffectinstead when reacting to specific data.- Watchers created in
<script setup>are auto-cleaned on unmount.