Skip to content

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.

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 here

In practice, onMounted and onUnmounted are the hooks you’ll use most often.

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.

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.

Runs just before the component is destroyed. The DOM is still accessible here, which is occasionally useful for saving state before the component disappears.

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.

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.

  1. Create a component with onMounted that logs “Component mounted!” to the console.
  2. Add an onUnmounted that logs “Component unmounted!”.
  3. Add a v-if toggle in a parent component that conditionally renders/destroys your component. Verify both messages appear at the right times.
  4. Use onMounted to auto-focus a text input using a template ref.
  • onMounted runs after the component is in the DOM — safe to access DOM elements and template refs.
  • onUnmounted runs when the component is removed — use it to clean up timers, listeners, and subscriptions.
  • onBeforeUnmount runs just before destruction — DOM still accessible.
  • onUpdated runs after every re-render — use watch/watchEffect instead when reacting to specific data.
  • Watchers created in <script setup> are auto-cleaned on unmount.