Vue.js: Component Lifecycle

Last updated: 2026-10-20

The component lifecycle is the whole journey of a Vue component from creation to destruction: instantiation → mounting to the DOM → data updates → unmounting. Vue provides 8 lifecycle hooks that let you run code at specific moments.

Mastering the lifecycle is what lets you write components that "breathe" — load data on mount, run side effects on update, and release resources on unmount.

1. What You'll Learn


2. The "Flicker" Problem of a Data-Loading Component

(1) Pain Point: the Component Renders Before the Data Arrives

Alice built a user profile component:

The user experience:

Product manager Charlie:

"Alice, users stare at 'undefined' for half a second. We need a loading state. Show 'Loading...' until the data arrives."

(2) The Vue Lifecycle + loading State Solution

The user experience:

(3) Benefits

After adding the lifecycle:


3. The Complete Lifecycle Diagram

100%
graph TB
    A[Create component instance] --> B[setup()]
    B --> C[setup reactivity]
    C --> D[setup()]
    D --> E[Template compilation]
    E --> F[onBeforeMount]
    F --> G[Mount to DOM]
    G --> H[onMounted]
    H --> I{Data updated?}
    I -->|Yes| J[onBeforeUpdate]
    J --> K[Re-render]
    K --> L[onUpdated]
    L --> I
    I -->|No| M{Component unmounted?}
    M -->|Yes| N[onBeforeUnmount]
    N --> O[Unmount]
    O --> P[onUnmounted]
    
    style H fill:#42b883,color:#fff
    style L fill:#42b883,color:#fff
    style P fill:#42b883,color:#fff

4. The 8 Lifecycle Hooks in Detail

(1) 8 Hooks Quick Reference

Hook When it fires Common use Frequency
onBeforeMount Before the component mounts Prepare data ⭐
onMounted After the component mounts Load data, DOM operations ⭐⭐⭐⭐⭐
onBeforeUpdate Before data updates Performance tuning ⭐⭐
onUpdated After data updates Work after the DOM re-renders ⭐⭐⭐
onBeforeUnmount Before the component unmounts Clear timers ⭐⭐⭐
onUnmounted After the component unmounts Final cleanup ⭐⭐
onErrorCaptured When a child error is caught Error boundaries ⭐⭐⭐
onActivated keep-alive activation Resume a cached component ⭐⭐
onDeactivated keep-alive deactivation Pause a cached component ⭐⭐

(2) onMounted: The Most Used

VUE
<script setup>
const { ref, onMounted } = Vue

const user = ref(null)

onMounted(async () => {
  // 1. Load the initial data
  const res = await fetch('/api/user')
  user.value = await res.json()
  
  // 2. DOM operations (touch the real DOM)
  document.title = `${user.value.name} - Dashboard`
  
  // 3. Register global event listeners
  const handleResize = () => { console.log('Window resized') }
window.addEventListener('resize', handleResize)
  
  // 4. Set up timers
  const timer = setInterval(() => {
    console.log('Tick')
  }, 1000)
  
  // ❌ Note: the timer and listener must be cleaned up in onUnmounted
})
</script>

(3) onUnmounted: Cleaning Up Resources

VUE
<script setup>
const { onMounted, onUnmounted } = Vue

let timer = null

onMounted(() => {
  timer = setInterval(() => console.log('Tick'), 1000)
  const handleResize = () => { console.log('Window resized') }
window.addEventListener('resize', handleResize)
})

// ✅ Cleanup: avoid memory leaks
onUnmounted(() => {
  clearInterval(timer)
  window.removeEventListener('resize', handleResize)
})
</script>

(4) onErrorCaptured: Error Boundaries

VUE
<!-- Usage in App.vue -->
<ErrorBoundary>
  <UserProfile :user-id="123" />  <!-- If it throws, ErrorBoundary catches it -->
</ErrorBoundary>

(5) 5 Use Cases

Scenario Hook Code
Load initial data onMounted await fetch(...)
Set up a timer onMounted + onUnmounted setInterval + clearInterval
Listen to global events onMounted + onUnmounted addEventListener + removeEventListener
DOM operations onMounted document.querySelector(...)
Third-party library integration onMounted + onUnmounted new Chart(...) + chart.destroy()

▶ Example: 8 Hooks Quick Reference

▶ Try it Yourself

Output:

TEXT
Two buttons, a blue panel reading Props count: 0, and a grey hint.
On load the console prints 1. onBeforeMount: about to mount then 2.
onMounted: mounted (hooks 7–9 stay silent: no error occurred and there is no keep-alive).
Clicking count++ prints 3. onBeforeUpdate: about to update followed by 4.
onUpdated: updated and updates the panel; clicking Unmount prints 5.
onBeforeUnmount: about to unmount then 6. onUnmounted: unmounted and removes the panel.
TEXT
count++ (0)   [Unmount]

Props count: 0

Check the console output

console:
1. onBeforeMount: about to mount
2. onMounted: mounted

▶ Example: onErrorCaptured Error Boundary

▶ Try it Yourself

Output:

TEXT
The buggy child renders first and is then replaced after ~100ms by a light-red banner reading ⚠️ Error: Cannot read properties of null (reading 'foo'), while the console logs Caught: ...
and Info: ....
Because the handler returns false, the error does not bubble up to the app-level handler, and the rest of the page keeps working.
TEXT
⚠️ Error: Cannot read properties of null (reading 'foo')

5. Parent/Child Lifecycle Execution Order

(1) Mount Order

100%
sequenceDiagram
    participant P as Parent
    participant C as Child
    
    P->>P: 1. Parent onBeforeMount
    P->>P: 2. Parent onMounted
    C->>C: 3. Child onBeforeMount
    C->>C: 4. Child onMounted
    
    Note over P,C: ❌ This is wrong: parent mounted should come after the child

Correct order:

100%
sequenceDiagram
    participant P as Parent
    participant C as Child
    
    P->>P: 1. Parent onBeforeMount
    C->>C: 2. Child onBeforeMount
    C->>C: 3. Child onMounted
    P->>P: 4. Parent onMounted
    
    Note over P,C: ✅ The parent mounts only after all of its children have mounted

(2) Full Execution Order (Nested Components)

TEXT
1. Parent setup()
2. Parent setup
3. Parent setup()
4. Parent onBeforeMount
5. Child setup()
6. Child setup
7. Child setup()
8. Child onBeforeMount
9. Child onMounted
10. Parent onMounted

(3) Unmount Order (Reversed)

TEXT
1. Parent onBeforeUnmount
2. Child onBeforeUnmount
3. Child onUnmounted
4. Parent onUnmounted

▶ Example: Parent/Child Lifecycle Order (Console Output)

▶ Try it Yourself

Output:

TEXT
A grey hint followed by a bordered parent box containing the text Parent component and a yellow child box reading Child component.
The console proves the ordering: 3. Child onMounted appears first and 4.
Parent onMounted (parent waits for child) second, because a parent only mounts after all of its children are mounted.
TEXT
Check the console: Child first, then Parent
┌─────────────────────────────┐
│ Parent component            │
│ ┌─────────────────────────┐ │
│ │ Child component         │ │
│ └─────────────────────────┘ │
└─────────────────────────────┘

console:
3. Child onMounted
4. Parent onMounted (parent waits for child)

6. keep-alive Cached Components

(1) What Is keep-alive?

<keep-alive> caches component instances and avoids repeated creation/destruction. It is commonly used for tab switching and route switching.

(2) 2 Extra Hooks

VUE
<!-- Child component: cached by keep-alive -->
<script setup>
const { onActivated, onDeactivated } = Vue

// When the component is activated (restored from the cache)
onActivated(() => {
  console.log('Component activated')
  // Reload data, restore the scroll position, etc.
})

// When the component is deactivated (switched away but kept in the cache)
onDeactivated(() => {
  console.log('Component deactivated')
  // Save state, pause timers, etc.
})
</script>

(3) 5 Use Cases

Scenario Approach
Tab switching Wrap the tab content in <keep-alive>
Route switching Wrap <router-view> in <keep-alive>
Dialog caching Wrap the dialog in <keep-alive>
List pages Cache the already-loaded list
Form pages Cache the unsubmitted form

▶ Example: keep-alive Cached Components

▶ Try it Yourself

Output:

TEXT
Three tab buttons (the active one is green) and a green Home panel with an increment button and the hint Switch away and back;
count is kept.
Clicking the counter a few times, switching to Profile and back leaves the count intact — onDeactivated / onActivated fire instead of unmount/mount.
Home mounted is logged only once, on the very first render.
TEXT
[Home] [Profile] [Settings]

┌──────────────────────────────────────┐
│ Home                                 │
│ [Count: 3]                           │
│ Switch away and back; count is kept  │
└──────────────────────────────────────┘

console:
🏠 Home mounted
🏠 Home activated
🏠 Home deactivated
👤 Profile mounted
👤 Profile activated

(1) 📊 5 Common Mistakes (Reference Only)

Mistake Symptom Fix
Using document at the top level of setup Server-side error Use onMounted
Not clearing timers Memory leak clear them in onUnmounted
Mutating props inside onMounted Vue warning Use emit instead
Not handling errors in async components Silent failure onErrorCaptured
Confusing the parent/child mounted order Debugging confusion Understand the "parent waits for children" rule

7. Complete Example: A User Profile Component

▶ Example: onMounted + onUnmounted (Load Data + Clean Up)

▶ Try it Yourself

Output:

TEXT
A button labeled Unmount Component and, below it, a bordered card that first shows Loading...
for about 500ms.
Then the card switches to Alice 1 and alice1@example.com, and the console logs ✅ Mounted: data loaded.
Clicking the button unmounts the component (the label becomes Mount Component), which logs 🧹 Unmounted: timer cleared and stops the 5-second tick;
clicking again remounts it and reloads the data.
TEXT
[Unmount Component]
┌──────────────────────────────┐
│ Loading...                   │
└──────────────────────────────┘
        ↓ after 500ms
┌──────────────────────────────┐
│ Alice 1                      │
│ alice1@example.com           │
└──────────────────────────────┘

❓ FAQ

Q What is the difference between onMounted and setup()?
A During setup() the component exists but the DOM does not (so you cannot touch the DOM). In onMounted the DOM is mounted (so you can). Loading data usually belongs in onMounted, which also avoids SSR problems.
Q Can lifecycle hooks be async?
A Yes. onMounted(async () => { await fetch(...) }) is valid. Vue does not wait for the async work to finish before continuing.
Q What is the difference between keep-alive's onActivated and onMounted?
A onMounted fires only once (the first mount). onActivated fires every time the component is restored from the cache. Tab switching triggers onActivated + onDeactivated (not onMounted + onUnmounted).
Q What errors can onErrorCaptured catch?
A 3 kinds: (1) render errors in child components; (2) errors in child lifecycle hooks; (3) errors in child watch callbacks. It cannot catch its own errors or asynchronous errors.
Q Can a parent listen to a child's lifecycle?
A Yes, with @hook: @hook:mounted="handleChildMounted". But props/emit communication is preferred over listening to lifecycle events directly.
Q How do Vue 2 lifecycle hooks differ from Vue 3?
A Vue 3 renamed them to onMounted (Vue 2 used mounted) and added onErrorCaptured plus onActivated/onDeactivated. Vue 2 hooks still work in Vue 3 (backwards compatible).
Q What happens to the lifecycle during SSR (server-side rendering)?
A onBeforeMount / onMounted / onBeforeUpdate / onUpdated do not fire on the server (there is no DOM). Only setup() / setup() / onBeforeUnmount / onUnmounted / onErrorCaptured fire.

📖 Summary


📝 Exercises

  1. Basic (difficulty ⭐) Implement a simple UserCard component:

    • Load the user data in onMounted (with a mock 1s delay)
    • Show loading → then show the user info
    • Print "Component destroyed" in onUnmounted
  2. Intermediate (difficulty ⭐⭐) Implement a Timer component:

    • Start the timer in onMounted (+1 every second)
    • Show the current number of seconds
    • Clear the timer in onUnmounted
    • Add a button to pause/resume (store the state in a ref)
  3. Challenge (difficulty ⭐⭐⭐) Build a complete tab system:

    1. TabContainer.vue: 3 tabs (Home/Profile/Settings)
    2. 3 tab content components
    3. Cache the components with <keep-alive>
    4. Log "X activated, Y deactivated" when switching tabs
    5. Load data in one tab with onMounted
    6. Switching away does not unmount (because of keep-alive), so the data is still there when you switch back
    7. Catch child errors with onErrorCaptured
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏