Vue Lifecycle Hooks

Understanding component lifecycle stages

♻️ What are Lifecycle Hooks?

Lifecycle hooks are special functions that let you run code at specific stages of a component's life: creation, mounting, updating, and destruction. They help you fetch data, set up timers, or clean up resources.


<!-- Using Lifecycle Hooks -->
<template>
  <div>{{ message }}</div>
</template>

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

const message = ref('Hello')

onMounted(() => {
  console.log('Component is mounted!')
  message.value = 'Component loaded!'
})

onUnmounted(() => {
  console.log('Component is being destroyed!')
})
</script>
                                    

Key Lifecycle Hooks

🚀

onMounted

Component added to DOM

onMounted(() => {
  // Fetch data, access DOM
})
🔄

onUpdated

After reactive data changes

onUpdated(() => {
  // React to updates
})
🗑️

onUnmounted

Component removed from DOM

onUnmounted(() => {
  // Cleanup resources
})
⚠️

onErrorCaptured

Catch errors from children

onErrorCaptured((err) => {
  console.error(err)
})

🔹 onMounted - Component Initialization

Run code after the component is added to the DOM:

<template>
  <div>
    <h2>User Profile</h2>
    <p v-if="loading">Loading...</p>
    <div v-else>
      <p>Name: {{ user.name }}</p>
      <p>Email: {{ user.email }}</p>
    </div>
  </div>
</template>

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

const user = ref({})
const loading = ref(true)

onMounted(async () => {
  console.log('Component mounted - fetching data')
  
  // Fetch user data
  const response = await fetch('/api/user')
  user.value = await response.json()
  loading.value = false
  
  console.log('Data loaded!')
})
</script>

🔹 onUpdated - React to Changes

Execute code after component updates:

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="count++">Increment</button>
    <p>Updates: {{ updateCount }}</p>
  </div>
</template>

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

const count = ref(0)
const updateCount = ref(0)

onUpdated(() => {
  updateCount.value++
  console.log('Component updated!')
  console.log('Current count:', count.value)
})
</script>

🔹 onUnmounted - Cleanup

Clean up resources before component is destroyed:

<template>
  <div>
    <p>Timer: {{ seconds }}s</p>
    <p>Mouse: {{ x }}, {{ y }}</p>
  </div>
</template>

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

const seconds = ref(0)
const x = ref(0)
const y = ref(0)
let timer = null

function handleMouseMove(event) {
  x.value = event.clientX
  y.value = event.clientY
}

onMounted(() => {
  // Start timer
  timer = setInterval(() => {
    seconds.value++
  }, 1000)
  
  // Add event listener
  window.addEventListener('mousemove', handleMouseMove)
})

onUnmounted(() => {
  // Clear timer
  clearInterval(timer)
  
  // Remove event listener
  window.removeEventListener('mousemove', handleMouseMove)
  
  console.log('Cleanup complete!')
})
</script>

🔹 onBeforeMount & onBeforeUpdate

Run code before mounting or updating:

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="message = 'Updated!'">Update</button>
  </div>
</template>

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

const message = ref('Initial')

onBeforeMount(() => {
  console.log('About to mount component')
  console.log('DOM not yet available')
})

onBeforeUpdate(() => {
  console.log('About to update component')
  console.log('Old message:', message.value)
})
</script>

🔹 Complete Lifecycle Example

See all lifecycle hooks in action:

<template>
  <div>
    <h2>Lifecycle Demo</h2>
    <p>Count: {{ count }}</p>
    <button @click="count++">Update</button>
  </div>
</template>

<script setup>
import { 
  ref, 
  onBeforeMount, 
  onMounted, 
  onBeforeUpdate, 
  onUpdated, 
  onBeforeUnmount, 
  onUnmounted 
} from 'vue'

const count = ref(0)

onBeforeMount(() => {
  console.log('1. onBeforeMount - Component about to mount')
})

onMounted(() => {
  console.log('2. onMounted - Component mounted to DOM')
})

onBeforeUpdate(() => {
  console.log('3. onBeforeUpdate - Before reactive data updates DOM')
})

onUpdated(() => {
  console.log('4. onUpdated - DOM updated with new data')
})

onBeforeUnmount(() => {
  console.log('5. onBeforeUnmount - About to unmount')
})

onUnmounted(() => {
  console.log('6. onUnmounted - Component destroyed')
})
</script>

🧠 Test Your Knowledge

Which lifecycle hook is best for fetching data from an API?