Medium15 minVue.js Fundamentals
UpdatedAug 5, 2026
Edit

Vue lifecycle hooks and cleanup

CONCEPTS:Vue Lifecycle Hooks

Question Variations

  • "Where should a component register and remove a window event listener?"
  • "Does `onMounted` run during SSR?"
  • "Why can calling `onUnmounted` after an await fail?"

Why This Is Asked

This assesses whether a candidate can attach browser or third-party work to the correct component lifetime. Interviewers expect a distinction between setup-time reactive logic, mounted DOM access, and unmounted cleanup, including why hooks must be registered synchronously.

Key Concepts

  • onMounted: Runs after the component’s DOM has been inserted on the client.
  • onUnmounted: Releases listeners, timers, subscriptions, and external resources.
  • SSR: Mounted hooks do not run during server-side rendering.
  • Synchronous registration: Lifecycle hooks must be called during setup, before an await boundary.

Question Variations

  • “Where should a component register and remove a window event listener?”
  • “Does onMounted run during SSR?”
  • “Why can calling onUnmounted after an await fail?”

Answers by Technology

+ Add Variant
Vue.jsImprove this answer ✏️

Expected Answer (Vue.js 3.5.40)

Composition API lifecycle hooks attach work to a component instance. Put DOM-dependent initialization, such as measuring an element or registering a browser listener, in onMounted because the component’s DOM exists at that point. Put the matching cleanup in onUnmounted so listeners, timers, subscriptions, and third-party instances do not outlive the component.

Hooks must be registered synchronously while the component is executing setup(). Calling a hook after an await can lose the active component instance, so Vue cannot associate cleanup with the correct component. Keep reactive calculations in computed or watch rather than using lifecycle hooks as a general update mechanism. onUpdated is for rare post-DOM-update integration work and must not mutate state, which could create a render loop.

For SSR, onMounted and onUnmounted do not run on the server. Browser APIs should therefore be accessed from mounted hooks or guarded appropriately. Vue 3.5.40 provides onActivated and onDeactivated for components cached by KeepAlive.

Why It Matters

Incorrect lifecycle management leaks event listeners and subscriptions, causing duplicate handlers and retained memory after navigation. It also causes SSR failures when browser-only APIs are accessed during server rendering.

Example Code

import { onMounted, onUnmounted, ref, type Ref } from 'vue';

export function useWindowWidth(): Readonly<Ref<number>> {
  const width = ref<number>(0);
  const updateWidth = (): void => {
    width.value = window.innerWidth;
  };

  onMounted(() => {
    updateWidth();
    window.addEventListener('resize', updateWidth);
  });
  onUnmounted(() => window.removeEventListener('resize', updateWidth));

  return width;
}

Common Mistakes

  • Registering cleanup only in a click handler: The listener then survives if the component unmounts before the user clicks, leaking resources.
  • Reading window during setup for SSR code: Setup can run on the server, where window does not exist.
  • Mutating reactive state inside onUpdated: The mutation schedules another update and can create an infinite update cycle.

Follow-up Questions

  • When does onMounted run relative to child components? (Answer: It runs after the component and its synchronous child components have mounted.)
  • What hook handles a cached view becoming visible again? (Answer: onActivated, paired with onDeactivated when it becomes inactive.)

References