100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
JavaScript

Lifecycle Hooks in the Composition API

Learn how onMounted, onUpdated, onUnmounted and other lifecycle hook functions let you run code at specific points in a component's life.

The Composition API in DepthIntermediate9 min readJul 9, 2026
Analogies

Lifecycle Hooks in the Composition API

Every Vue component goes through a predictable sequence of phases: it's created, mounted to the DOM, updated in response to reactive changes, and eventually unmounted. The Composition API exposes these phases as importable functions — onMounted, onUpdated, onUnmounted, and others — that register a callback to run at that specific point. This is a direct evolution of the Options API's mounted, updated, and unmounted methods, but as functions they can be called multiple times, imported into composables, and organized by feature rather than by lifecycle stage.

🏏

Cricket analogy: A player's day goes through toss, batting, fielding, and end-of-play phases — the Composition API's onMounted/onUpdated/onUnmounted are like being able to call "start batting routine" as a reusable function from any drill, not just a fixed spot in the coach's rulebook.

The core hooks

onMounted fires after the component has been inserted into the DOM — the right place to measure DOM elements, initialize third-party libraries, or start data fetching that depends on rendered elements. onUpdated fires after the DOM has re-rendered due to a reactive data change. onUnmounted fires right before the component instance is destroyed and removed, making it the correct place to clean up timers, event listeners, or subscriptions to avoid memory leaks.

🏏

Cricket analogy: onMounted is like a groundskeeper inspecting the pitch only after it's fully rolled and marked — measuring moisture readings that only make sense once the surface exists; onUnmounted is like packing away the covers once play ends for the day.

vue
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

const windowWidth = ref(window.innerWidth)

function handleResize() {
  windowWidth.value = window.innerWidth
}

onMounted(() => {
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
})
</script>

Other hooks and setup itself

There is no onCreated hook because setup() itself (or the top level of <script setup>) already runs at the point equivalent to the Options API's created hook — any code written there executes before mounting. Additional hooks include onBeforeMount, onBeforeUpdate, onBeforeUnmount, onErrorCaptured (catches errors from descendant components), onActivated/onDeactivated (for components inside <KeepAlive>), and onRenderTracked/onRenderTriggered for debugging reactivity.

🏏

Cricket analogy: There's no separate "team selected" hook because the moment the squad sheet is handed in, that's already equivalent to "created" — additional checkpoints like onBeforeMount (warm-up) exist, and onErrorCaptured is like a captain intercepting a fielding mistake before it costs runs, catching it from a junior player.

javascript
import { onErrorCaptured } from 'vue'

onErrorCaptured((err, instance, info) => {
  console.error('Captured error from child:', err, info)
  // return false to stop the error from propagating further
  return false
})

Hooks inside composables

Because lifecycle hooks are plain function calls rather than component options, they can be called inside a composable function and still correctly attach to whichever component invoked that composable. This is what allows reusable logic like useMousePosition() or useFetch() to register its own onMounted/onUnmounted cleanup, entirely encapsulated away from the consuming component.

🏏

Cricket analogy: A reusable "review-drill" routine that any junior player can call still correctly logs onto that specific player's own training record — like a composable's onMounted/onUnmounted attaching to whichever component invoked it, keeping useFetch-style logic encapsulated per user.

In the Options API, mounted, updated, etc. are object properties, so a component can only define each one once. In the Composition API, you can call onMounted multiple times in the same component (or across multiple composables it uses), and all registered callbacks run in the order they were registered.

Lifecycle hook functions like onMounted must be called synchronously during setup() (or the top-level of <script setup>) — calling them inside an async function after an await, or inside a setTimeout, silently fails to register them correctly because Vue relies on tracking the 'currently active component instance' at call time.

  • Lifecycle hooks are imported functions (onMounted, onUpdated, onUnmounted, etc.) that register callbacks for specific component life stages.
  • onMounted runs after DOM insertion; onUpdated after reactive re-renders; onUnmounted right before teardown for cleanup.
  • There is no onCreated hook — setup()/<script setup> top-level code already runs at that point.
  • onErrorCaptured lets a component catch errors thrown by descendant components.
  • Hooks can be called inside composables, letting reusable logic manage its own mount/unmount behavior transparently.
  • Hooks must be registered synchronously during setup — calling them after an await or inside a timeout breaks registration.

Practice what you learned

Was this page helpful?

Topics covered

#JavaScript#VueJsStudyNotes#WebDevelopment#LifecycleHooksInTheCompositionAPI#Lifecycle#Hooks#Composition#API#APIs#StudyNotes#SkillVeris