Lifecycle Hooks

Back

Loading concept...

🎭 Vue.js Lifecycle Hooks: The Story of a Component’s Life

The Big Picture 🌟

Imagine a butterfly. It goes through amazing stages: egg → caterpillar → cocoon → beautiful butterfly → eventually says goodbye.

Your Vue component is just like that butterfly! It has its own life stages, and at each stage, you can do special things. These special moments are called Lifecycle Hooks.


🦋 The Four Life Stages

graph TD A["🥚 BIRTH - Mount Hooks"] --> B["🐛 LIVING - Update Hooks"] B --> C["🦋 GOODBYE - Unmount Hooks"] D["🛡️ ERROR GUARD - onErrorCaptured"] D -.-> A D -.-> B D -.-> C
Stage What Happens Real Life Example
Mount Component is born Baby opens eyes
Update Component changes Kid grows taller
Unmount Component leaves Saying goodbye
Error Something goes wrong Doctor catches illness

🥚 Mount Lifecycle Hooks

When: Your component is being born and placed on the screen.

Think of it like a new student joining a classroom:

  1. First, the student gets ready at home (setup)
  2. Then, the student walks into the classroom (mount)

onBeforeMount

What: Runs RIGHT BEFORE your component appears on screen.

Analogy: The student is standing at the door, about to walk in. The desk isn’t assigned yet!

import { onBeforeMount } from 'vue'

onBeforeMount(() => {
  console.log('About to appear!')
  // ⚠️ Can't touch the screen yet
  // The DOM doesn't exist
})

When to Use onBeforeMount:

  • ✅ Setting up data before display
  • ✅ Preparing things that don’t need the screen
  • ❌ NOT for touching buttons or text on screen

onMounted

What: Runs AFTER your component is on the screen.

Analogy: The student has sat down at their desk. Now they can write on the board!

import { onMounted } from 'vue'

onMounted(() => {
  console.log('I am on screen!')
  // ✅ NOW you can touch the DOM
  const button = document.querySelector('button')
  button.focus()
})

Real Example: Fetching Data

import { ref, onMounted } from 'vue'

const users = ref([])
const loading = ref(true)

onMounted(async () => {
  // Fetch data when component appears
  const response = await fetch('/api/users')
  users.value = await response.json()
  loading.value = false
})

When to Use onMounted:

  • ✅ Fetching data from a server
  • ✅ Setting up timers or intervals
  • ✅ Connecting to external libraries (charts, maps)
  • ✅ Focusing on input fields

🎯 Mount Hooks Summary

graph TD A["Component Created"] --> B["onBeforeMount"] B --> C["Template Renders"] C --> D["onMounted"] D --> E["✨ Component Ready!"] style B fill:#FFE4B5 style D fill:#90EE90
Hook DOM Available? Use Case
onBeforeMount ❌ No Setup data, no screen touch
onMounted ✅ Yes Fetch data, use libraries

🐛 Update Lifecycle Hooks

When: Your component’s data changes and it needs to redraw.

Think of it like a whiteboard being erased and rewritten:

  1. Teacher says “I’m about to change the board”
  2. Teacher erases and writes new stuff
  3. “Done! Look at the new board!”

onBeforeUpdate

What: Runs RIGHT BEFORE the screen updates.

Analogy: The teacher raised the eraser but hasn’t erased yet.

import { onBeforeUpdate } from 'vue'

onBeforeUpdate(() => {
  console.log('About to change!')
  // The OLD content is still on screen
  // Perfect for saving scroll position
})

Real Example: Save Scroll Position

import { ref, onBeforeUpdate } from 'vue'

const savedScrollTop = ref(0)

onBeforeUpdate(() => {
  // Save where user was scrolling
  const chatBox = document.querySelector('.chat')
  if (chatBox) {
    savedScrollTop.value = chatBox.scrollTop
  }
})

onUpdated

What: Runs AFTER the screen finishes updating.

Analogy: The teacher finished writing. New content is visible!

import { onUpdated } from 'vue'

onUpdated(() => {
  console.log('Screen updated!')
  // The NEW content is now on screen
})

Real Example: Restore Scroll Position

import { ref, onUpdated } from 'vue'

onUpdated(() => {
  // Keep user at same scroll position
  const chatBox = document.querySelector('.chat')
  if (chatBox) {
    chatBox.scrollTop = savedScrollTop.value
  }
})

⚠️ Warning: Infinite Loop Danger!

// 🚫 DON'T DO THIS!
onUpdated(() => {
  count.value++ // This triggers another update!
  // Creates infinite loop!
})

// ✅ DO THIS instead
onUpdated(() => {
  // Only READ, don't change reactive data
  console.log('Count is now:', count.value)
})

🎯 Update Hooks Summary

graph TD A["Data Changes"] --> B["onBeforeUpdate"] B --> C["Screen Redraws"] C --> D["onUpdated"] D --> E["✨ Update Complete!"] style B fill:#FFE4B5 style D fill:#90EE90
Hook What You See Best For
onBeforeUpdate OLD screen Save state
onUpdated NEW screen React to changes

🦋 Unmount Lifecycle Hooks

When: Your component is leaving the screen forever.

Think of it like cleaning up your room before moving out:

  1. “I’m about to leave” (pack boxes)
  2. “Goodbye, room!” (door closes)

onBeforeUnmount

What: Runs RIGHT BEFORE component is removed.

Analogy: You’re still in the room, packing your bags.

import { onBeforeUnmount } from 'vue'

onBeforeUnmount(() => {
  console.log('Cleaning up...')
  // Stop timers, close connections
  // Component is STILL on screen
})

onUnmounted

What: Runs AFTER component is completely gone.

Analogy: You’ve left the building. The room is empty.

import { onUnmounted } from 'vue'

onUnmounted(() => {
  console.log('Component is gone!')
  // Final cleanup
  // Component is NO LONGER on screen
})

🧹 Why Cleanup Matters

Imagine you turn on a faucet (timer) but forget to turn it off. Water floods everywhere!

Real Example: Timer Cleanup

import { ref, onMounted, onUnmounted } from 'vue'

const seconds = ref(0)
let timer = null

onMounted(() => {
  // Start a timer
  timer = setInterval(() => {
    seconds.value++
  }, 1000)
})

onUnmounted(() => {
  // STOP the timer!
  // If we forget, it keeps running
  // even after component is gone!
  clearInterval(timer)
})

Real Example: Event Listener Cleanup

import { onMounted, onUnmounted } from 'vue'

const handleResize = () => {
  console.log('Window resized!')
}

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

onUnmounted(() => {
  // Remove listener!
  window.removeEventListener('resize', handleResize)
})

🎯 Unmount Hooks Summary

graph TD A["Time to Leave"] --> B["onBeforeUnmount"] B --> C["Component Removed"] C --> D["onUnmounted"] D --> E["💨 Gone Forever!"] style B fill:#FFE4B5 style D fill:#FFB6C1
Hook Component Status Use Case
onBeforeUnmount Still visible Start cleanup
onUnmounted Gone Final cleanup

What to Clean Up:

  • ⏱️ Timers (setInterval, setTimeout)
  • 📡 Event listeners
  • 🔌 WebSocket connections
  • 📊 Third-party library instances

🛡️ onErrorCaptured

What: Catches errors from child components.

Think of it like a safety net at a circus. If a trapeze artist (child component) falls, the net (parent) catches them!

graph TD A["Parent Component"] --> B["Child Component"] B --> C["Grandchild Component"] C -->|Error!| D["💥 Crash!"] D -->|Caught by| A style A fill:#90EE90 style D fill:#FF6B6B

Basic Usage

import { onErrorCaptured, ref } from 'vue'

const error = ref(null)

onErrorCaptured((err, instance, info) => {
  // err = the error object
  // instance = component that broke
  // info = what was happening

  error.value = err.message
  console.log('Caught error:', err)

  // Return false to STOP error
  // from going higher up
  return false
})

The Three Parameters

Parameter What It Is Example
err The error itself Error: Cannot read property
instance Broken component The child that crashed
info What was happening "mounted hook"

Real Example: Error Boundary

<template>
  <div v-if="hasError" class="error-box">
    😱 Something broke!
    <button @click="retry">Try Again</button>
  </div>
  <slot v-else></slot>
</template>

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

const hasError = ref(false)

onErrorCaptured((err) => {
  hasError.value = true
  console.error('Child error:', err)
  return false // Stop propagation
})

const retry = () => {
  hasError.value = false
}
</script>

When to Use onErrorCaptured:

  • ✅ Creating “Error Boundary” components
  • ✅ Logging errors to a server
  • ✅ Showing user-friendly error messages
  • ✅ Preventing entire app from crashing

🎬 The Complete Picture

graph TD subgraph Mount A["onBeforeMount"] --> B["onMounted"] end subgraph Update C["onBeforeUpdate"] --> D["onUpdated"] end subgraph Unmount E["onBeforeUnmount"] --> F["onUnmounted"] end B --> C D --> C D --> E G["onErrorCaptured"] -.-> A G -.-> C G -.-> E style B fill:#90EE90 style D fill:#87CEEB style F fill:#FFB6C1 style G fill:#DDA0DD

🚀 Quick Reference Table

Hook When DOM? Common Use
onBeforeMount Before appearing Pre-setup
onMounted After appearing Fetch data, init libraries
onBeforeUpdate Before redraw OLD Save scroll position
onUpdated After redraw NEW React to changes
onBeforeUnmount Before leaving Start cleanup
onUnmounted After leaving Final cleanup
onErrorCaptured Child error Error handling

💡 Pro Tips

1. Always Clean Up!

If you start something in onMounted, stop it in onUnmounted.

2. Don’t Change Data in onUpdated

Reading is fine. Changing reactive data causes infinite loops!

3. Use onErrorCaptured for Safety

Wrap risky child components so errors don’t crash your whole app.

4. Most Common Hook: onMounted

You’ll use this the most for fetching data and setting up things.


🎉 You Did It!

You now understand the complete lifecycle of a Vue component:

  1. 🥚 Mount - Component is born
  2. 🐛 Update - Component changes
  3. 🦋 Unmount - Component says goodbye
  4. 🛡️ Error - Catching problems

Just like a butterfly, every Vue component goes through its beautiful lifecycle. And now YOU control what happens at each stage! 🦋✨

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.