🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
HTML MASTER CLASS /// LEARN TAGS /// BUILD STRUCTURE /// SEMANTIC WEB /// HTML MASTER CLASS /// LEARN TAGS ///

Lifecycle Hooks in Vue.js

Learn about Lifecycle Hooks in this comprehensive Vue.js tutorial. Learn how to run code at specific moments in a component’s life: setup, mounting, updating, and unmounting.

Total XP: 0|💻 vuejs XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

Select an unlocked node to view details root

🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

Control the flow of time in your components.

1The Component Lifecycle

A component is instantiated, its template is compiled, it is attached to the DOM (mounted), it updates when data changes, and finally, it is destroyed (unmounted). Vue gives you hooks to run code at each of these stages.

2onMounted

onMounted is the most frequently used hook. It runs after the component has been inserted into the DOM. This is the perfect place to fetch data from an API, initialize a 3D canvas, or interact with native DOM elements.

3onUnmounted

onUnmounted runs right before the component is destroyed. It is absolutely critical for performance: you must use it to remove manual window.addEventListener listeners or clear setInterval timers to prevent memory leaks.

4Step-by-Step Breakdown

Every Vue component goes through a lifecycle: It is created, it is mounted to the DOM, it updates when data changes, and it is unmounted when destroyed.

You can hook into these specific moments using Lifecycle Hooks. The most common one is onMounted.

Which lifecycle hook is typically used to fetch initial data from an API because it runs exactly when the component is added to the DOM?

  • onCreated
  • onMounted
  • onUpdated

Why wait for onMounted? Because before onMounted, the HTML elements do not exist yet! If you try to access a DOM element before it mounts, it will be null.

Another important hook is onUnmounted. This runs right before the component is destroyed (e.g., when you navigate to another page).

Which hook should you use to clean up event listeners or setInterval timers so they don't cause memory leaks when the component disappears?

  • onDestroyed
  • onUnmounted
  • onBeforeMount

If you need to know when the DOM updates due to a reactive variable changing, use onUpdated.

Note: In Vue 3 with <script setup>, you do not need onCreated. Any code written directly inside the script block runs during the setup phase (which replaces created).

In Vue 3 with <script setup>, do you need to explicitly use an onCreated hook to run code when the component is initialized?

  • Yes, it is mandatory
  • No, just write code in the script block

Mastering the lifecycle means you never get "Cannot read property of null" errors when accessing the DOM, and you never create memory leaks.

Level Up 🚀

Advanced cheat sheets, SEO tricks, and interview prep for this topic.

Browser Support

ChromeSupported

Fully supported.

FirefoxSupported

Fully supported.

SafariSupported

Fully supported.

EdgeSupported

Fully supported.

Accessibility (A11y)

1Managing Focus in onMounted

onMounted is the correct hook to call el.focus() on an input the moment a modal opens, since the element is guaranteed to exist in the DOM by then — this is what lets keyboard and screen-reader users land directly on the first interactive field instead of losing their position when a dialog appears.

const inputRef = ref(null); onMounted(() => inputRef.value?.focus());

SEO Implications

  • 1

    onMounted Never Runs During Server-Side Rendering

    onMounted only fires in the browser, by design — Vue's SSR renderer produces the initial HTML string without a real DOM, so any content generated inside onMounted is completely absent from what a crawler receives before JavaScript executes, unlike content computed during setup() itself, which SSR does include.

Best Practices

Pair Every Listener Registered in onMounted with Cleanup in onUnmounted

Any window.addEventListener, setInterval, or third-party subscription started in onMounted must be torn down in the matching onUnmounted call; otherwise it keeps running every time the component is created and destroyed, a classic Vue memory leak.

Frequent Bugs

THE BUG

Accessing a template ref before the component has mounted.

THE FIX

A ref bound to a DOM element via <div ref="boxRef"> is null until after mounting completes. Reading boxRef.value in setup()'s top-level code (outside onMounted) will always be null — move the access inside onMounted(() => { ... }).

Real-World Examples

Real-Time Dashboard Polling

A metrics dashboard starts a setInterval poll in onMounted to refresh data every 5 seconds and explicitly clears it in onUnmounted, so navigating away from the dashboard route stops the network requests instead of leaving a zombie timer running.

let timer;
onMounted(() => {
  timer = setInterval(fetchMetrics, 5000);
});
onUnmounted(() => clearInterval(timer));

Interview Prep

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Mutating a Prop Directly

// Wrong const props = defineProps(['count']); function increment() { props.count++; } // Correct const emit = defineEmits(['update:count']); function increment() { emit('update:count', props.count + 1); }

The Solution //

A child component should never assign to a prop it received (e.g. props.title = 'New'). Vue logs "Unexpected mutation of prop" because props are a one-way binding. Copy the prop into local state with ref()/computed() first, or emit an event asking the parent to change its own data.

The Error //

Losing Reactivity by Destructuring reactive()

// Wrong const { name } = reactive({ name: 'Alice' }); // name is now a static string // Correct const state = reactive({ name: 'Alice' }); const { name } = toRefs(state); // name is a live ref

The Solution //

Destructuring a reactive() object copies its properties out as disconnected plain values, so future mutations of the original object won't update the destructured variables. Keep referencing the object's properties directly, or convert it with toRefs() before destructuring.

Continue Learning