Vue JS Lifecycle Hooks 1 — Questions and Answers
Question 1: What is the correct order of Vue 3 component lifecycle hooks for an initial mount?
- setup → onBeforeMount → onMounted (Correct answer)
- onMounted → setup → onBeforeMount
- onBeforeMount → setup → onMounted
- setup → onMounted → onBeforeMount
Correct answer: setup → onBeforeMount → onMounted
The `setup()` function (or `<script setup>`) runs first during component initialization, then `onBeforeMount` fires before DOM insertion, and `onMounted` fires after the component is in the DOM.
Vue 3's mount lifecycle order: 1) `setup()` runs (reactive state, computed, watchers are initialized) 2) `onBeforeMount` fires — the component tree is compiled but not yet inserted into the DOM 3) The component renders and the DOM is created 4) `onMounted` fires — the component is in the DOM and `$el` is available. In Options API, the equivalent sequence is: `beforeCreate` → `created` (both replaced by `setup()`) → `beforeMount` → `mounted`. Note: child components are mounted before the parent's `onMounted` fires.
Question 2: When does `onMounted` fire in Vue 3?
- After the component has been mounted — the DOM is available and all child components are mounted (Correct answer)
- Before the component's first render
- When the component receives new props
- When the component is about to be destroyed
Correct answer: After the component has been mounted — the DOM is available and all child components are mounted
`onMounted` fires after the component is fully mounted in the DOM, including all synchronous child components. It's safe to access DOM elements and interact with third-party libraries here.
`onMounted` is the most commonly used lifecycle hook. It fires once after the component's first render and DOM insertion. All synchronous child components are also mounted by the time parent's `onMounted` fires. Safe uses: querying DOM nodes with `$el` or template refs, initializing third-party libraries that need a DOM container (charts, maps, sliders), starting subscriptions, and initial data fetching. Avoid direct DOM manipulation that could conflict with Vue's rendering — prefer reactive data when possible.
Question 3: What is the purpose of `onBeforeUnmount` in Vue 3?
- Runs just before a component is removed from the DOM — ideal for cleanup like removing event listeners and canceling timers (Correct answer)
- Fires before route navigation away from the component
- Runs before the component's props update
- Cancels pending re-renders before unmounting
Correct answer: Runs just before a component is removed from the DOM — ideal for cleanup like removing event listeners and canceling timers
`onBeforeUnmount` fires when the component is about to be unmounted but is still fully functional. It's the last chance to clean up side effects before the component is destroyed.
`onBeforeUnmount` fires just before `onUnmounted`. At this point, the component instance is still fully functional — all reactive data and methods are accessible. This is the perfect place to clean up: `clearInterval(timerId)`, `window.removeEventListener(...)`, `observer.disconnect()`, canceling API requests. Not cleaning up causes memory leaks. Vue composables that set up side effects should register their cleanup here. Note: effects created with `watch`, `watchEffect`, and `computed` inside `setup()` are automatically cleaned up on unmount.
Question 4: Which lifecycle hook should you use to fetch initial data when a component loads?
- onMounted (or created/setup for non-DOM dependent fetches) (Correct answer)
- onUpdated
- onBeforeMount
- onActivated
Correct answer: onMounted (or created/setup for non-DOM dependent fetches)
Data fetching is typically done in `onMounted`. If the fetch doesn't need DOM access, you can also start it in `setup()` directly, which runs slightly earlier.
For data fetching, `onMounted` is the standard choice in Composition API. If you're using async/await, you'd use `onMounted(async () => { data.value = await fetchData() })` or create an async composable. Fetching in `setup()` directly also works for non-DOM-dependent data: `const data = ref(null); fetchData().then(d => data.value = d)`. The advantage of `onMounted` is that it only runs client-side in SSR scenarios, preventing hydration issues. During SSR, `onMounted` is not called, so data should be fetched during server rendering using different means (e.g., `asyncData` in Nuxt).
Question 5: What is `onActivated` and `onDeactivated` used for in Vue 3?
- Hooks for components kept alive by `<KeepAlive>` — fire when the component enters/leaves the cache (Correct answer)
- Hooks for Vue Router navigation
- Hooks for Pinia store activation
- Lifecycle hooks for async components
Correct answer: Hooks for components kept alive by `<KeepAlive>` — fire when the component enters/leaves the cache
`onActivated` fires when a `<KeepAlive>` cached component is re-inserted into the DOM. `onDeactivated` fires when it's removed from DOM but kept in the cache.
`<KeepAlive>` wraps dynamic components or routed views to cache them instead of destroying them when they're deactivated. Instead of `onMounted`/`onUnmounted` firing on every activation, Vue fires `onActivated` when the cached component enters the view and `onDeactivated` when it leaves. Use `onActivated` to refresh data that might have changed while the component was cached and `onDeactivated` for cleanup that should happen when leaving the view. `onMounted` still fires on the very first mount.
Question 6: How do you use the `onErrorCaptured` hook in Vue 3?
- Register a hook that receives errors from descendant components: onErrorCaptured((err, instance, info) => { ... }) (Correct answer)
- Wrap async operations in a try/catch inside setup()
- Use the global app.config.errorHandler instead
- onErrorCaptured is not available in Composition API
Correct answer: Register a hook that receives errors from descendant components: onErrorCaptured((err, instance, info) => { ... })
`onErrorCaptured` receives errors thrown from any descendant component's rendering, lifecycle hooks, or event handlers, enabling parent components to handle errors gracefully.
`onErrorCaptured((err, instance, info) => { handleError(err); return false })` registers an error boundary for the component's subtree. It receives the error, the component instance that threw it, and an info string describing the hook/phase where the error occurred. Return `false` to stop the error from propagating further up. Return nothing (or true) to let it continue propagating. This is used to build error boundary components that show fallback UIs. For global unhandled errors, use `app.config.errorHandler`. Vue Router also has its own error handling.
What is the correct order of Vue 3 component lifecycle hooks for an initial mount?