Skip to content

Vue Developer interview questions

100 real questions with model answers and explanations for Vue Developer candidates.

See a Vue Developer resume example

Practice with flashcards

Spaced repetition · Hunter Pass

Questions

composablesvueoop

A composable owns one coherent piece of reactive behavior and exposes a small explicit contract.

  • Inputs should reveal dependencies through values, refs, getters, or injected services rather than hidden component assumptions.
  • Returned state and operations should have stable meanings, with readonly state when callers should mutate only through actions.
  • Watchers, listeners, and requests created by the composable need lifecycle-aware cleanup.

Why interviewers ask this: The interviewer checks whether composables encapsulate behavior rather than merely move setup code into another file.

composables

Reactive state created inside the composable function is normally per call, while module-scope state is shared across calls.

  • Per-call state gives each component instance an independent lifecycle and value.
  • Module-scope refs can implement deliberate singleton state but also outlive component unmounts.
  • Shared module state needs special care in server rendering because requests must not leak data into one another.

Why interviewers ask this: A strong answer understands how declaration location controls composable state ownership.

reactreactivitycomposables

Accept a flexible reactive input type and normalize it only when reading the current value.

  • toValue reads a plain value, unwraps a ref, or calls a getter.
  • Reading toValue inside watchEffect tracks a ref or getter dependency for later updates.
  • Normalizing once outside an effect would capture only the current value and discard future reactive changes.

Why interviewers ask this: The interviewer checks whether flexible composable inputs preserve their reactive behavior.

composables

onScopeDispose registers cleanup with the active reactive effect scope that created the composable.

  • It can stop timers, subscriptions, observers, and other resources without requiring a component-specific hook.
  • When called during component setup, the component's scope disposes the cleanup on unmount.
  • It also works when the composable runs inside a manually created effectScope.

Why interviewers ask this: A strong answer uses scope ownership so composables are reusable both inside and outside components.

reactreactivityvue

effectScope groups computed values, watchers, and watch effects so they can be stopped together.

  • Effects created while a scope is active become children of that scope.
  • Calling stop disposes the grouped effects and their registered cleanup.
  • It is useful for reusable services or temporary reactive subsystems whose lifetime is not exactly one component.

Why interviewers ask this: The interviewer checks whether non-component reactive work has an explicit lifecycle owner.

reactreactivitycomponents

Provide reactive state together with a narrow interface that preserves one clear mutation owner.

  • A provided ref or reactive object stays reactive for descendants that inject the same value.
  • readonly prevents descendants from writing directly when the provider should control changes.
  • Named actions can be provided beside the state so updates remain explicit and searchable.

Why interviewers ask this: A strong answer preserves reactivity without turning dependency injection into uncontrolled shared mutation.

componentsvueinjection

An InjectionKey connects the provided and injected TypeScript type while giving the dependency a collision-resistant symbol identity.

  • The key can describe a context interface containing readonly state and operations.
  • inject returns a possibly undefined value unless a default or required-provider helper removes that case.
  • Exporting one key from the context module keeps providers and consumers on the same contract.

Why interviewers ask this: The interviewer checks type-safe dependency injection and deliberate handling of a missing provider.

hookscomposition-apiapi

Vue needs the current component instance to associate each hook with the correct lifecycle.

  • setup and script setup establish that active instance while their synchronous code runs.
  • Registering a hook after an unrelated await may occur after the active instance context is gone.
  • Async work may run inside a registered hook, but the hook registration itself should happen during setup.

Why interviewers ask this: A strong answer connects hook timing to component-instance ownership rather than style preference.

componentshookscomposables

Use hooks only for resources whose lifetime should naturally follow the caller's component scope.

  • Register DOM or browser setup in onMounted and release it in onUnmounted or onScopeDispose.
  • Keep non-DOM reactive state available during setup so callers can use it in the first render.
  • Expose explicit start and stop operations when the caller, rather than component mount, should control the resource.

Why interviewers ask this: The interviewer checks whether lifecycle coupling follows the actual ownership of a composable resource.

vuedependencies

A ref object tracks effects that read its value property and triggers them when that property changes.

  • Object values assigned to a normal ref are converted to reactive proxies.
  • Vue compares a new assignment with the previous raw value before notifying dependencies.
  • The stable wrapper identity allows a ref to remain reactive even when its contained value is replaced.

Why interviewers ask this: A strong answer explains why ref supports replacement while preserving dependency identity.

reactreactivity

reactive returns a Proxy whose identity differs from the original raw object and whose access enables tracking.

  • Repeated reactive calls for the same raw object return the same proxy.
  • Mutating or passing the raw object can bypass consumers that depend on proxy access.
  • toRaw can retrieve the original temporarily, but keeping raw references for application state undermines consistent reactivity.

Why interviewers ask this: The interviewer checks whether proxy and raw identities are handled without splitting the reactive data flow.

reactreactivity

A ref keeps one reactive wrapper while its value can point to a different object after assignment.

  • Assigning a new object to ref.value notifies effects that read the ref.
  • A reactive variable relies on consumers using its existing proxy, so replacing the local variable does not update those consumers.
  • Object.assign can update an existing reactive proxy when preserving its identity is the intended model.

Why interviewers ask this: A strong answer chooses the primitive according to whether state identity or contained value is replaceable.

reactreactivity

They create ref interfaces whose reads and writes forward to properties of the original reactive source.

  • toRef targets one property and can preserve a link even when that property is currently absent.
  • toRefs converts the source's enumerable properties into a matching object of linked refs.
  • They are useful for destructuring, while plain destructuring copies current primitive values and loses proxy tracking.

Why interviewers ask this: The interviewer checks whether property-level refs remain synchronized with their source object.

reactivity

Use shallowRef when Vue should react to replacement of the top-level value but not proxy its nested contents.

  • It suits large immutable structures, external state systems, or third-party class instances.
  • Nested mutation does not trigger dependent effects because only access to the value property is tracked.
  • Replacing shallow.value with a new identity triggers updates and keeps the reactivity boundary explicit.

Why interviewers ask this: A strong answer uses shallowRef to avoid unwanted deep conversion rather than as a generic optimization.

reactivity

triggerRef manually notifies effects after an in-place nested mutation that shallowRef would not observe.

  • The shallow wrapper normally reacts only when its value property receives a new identity.
  • Manual triggering can integrate an external mutable object whose update cannot be represented by replacement.
  • Immutable replacement is usually clearer because it avoids hidden mutations followed by a separate notification step.

Why interviewers ask this: The interviewer checks whether manual invalidation is understood as an explicit escape hatch.

readonly prevents writes throughout a deeply converted object graph, while shallowReadonly protects only root properties.

  • Both return proxies that warn on attempted writes rather than freezing the original object.
  • Nested objects reached through readonly are also readonly proxies.
  • Nested objects inside shallowReadonly remain mutable, which is useful only when that boundary is intentional.

Why interviewers ask this: A strong answer distinguishes proxy write protection at deep and top-level boundaries.

vue

markRaw prevents an object from being converted into a reactive proxy when proxying is inappropriate.

  • It can suit component definitions, complex library instances, or values whose identity must remain raw.
  • Nested values are not automatically marked, so mixing raw and proxied branches can create identity hazards.
  • It should define a deliberate integration boundary rather than disable reactivity broadly for convenience.

Why interviewers ask this: The interviewer checks whether raw opt-outs are narrow and motivated by object semantics.

reactivitycaching

A computed ref caches its last result and becomes dirty when one of its tracked reactive dependencies changes.

  • Reading the computed getter records whichever reactive values are actually used on that execution path.
  • Dependency changes invalidate the cache, but the getter remains lazy until the computed value is read again.
  • Multiple consumers can read the same cached result without rerunning the getter for each consumer.

Why interviewers ask this: A strong answer explains both lazy evaluation and dependency-based invalidation.

reactivity

A writable computed ref should present a reversible view over source state rather than create a second source of truth.

  • Its getter derives the exposed value from reactive sources.
  • Its setter translates an assignment into updates of those same sources.
  • If a transformation cannot be reversed clearly, an explicit action or local draft state is less surprising.

Why interviewers ask this: The interviewer checks whether writable computed state maintains a coherent ownership model.

design

customRef gives explicit control over when reads are tracked and when writes trigger dependent effects.

  • Its factory receives track and trigger functions and returns custom get and set behavior.
  • Debounced or externally synchronized refs are common uses.
  • The implementation should preserve stable value semantics because returning a new object on every get can cause confusing child updates.

Why interviewers ask this: A strong answer understands customRef as control over invalidation, not only a debounce helper.

Locked questions

  • 21

    Which source forms can watch observe in the Composition API?

    composition-apiapioop
  • 22

    How does watching a reactive object differ from watching a getter that returns that object?

    reactreactivity
  • 23

    What are the costs and semantics of a deep watcher?

    reactivity
  • 24

    What does the flush option change for a Vue watcher?

    reactivityvue
  • 25

    How should a watcher clean up stale side effects?

    reactivity
  • 26

    How does dependency tracking work in an async watchEffect?

    reactivityasyncdependencies
  • 27

    How do you choose among computed, watch, and watchEffect?

    reactivity
  • 28

    How do Options stores and Setup stores differ in Pinia?

    composition-apistate-management
  • 29

    What responsibilities belong in Pinia state, getters, and actions?

    state-management
  • 30

    How do direct mutation and $patch differ in Pinia?

    state-management
  • 31

    Why is storeToRefs needed when destructuring a Pinia store?

    state-managementdestructuring
  • 32

    What can a Pinia plugin add to stores?

    state-management
  • 33

    How do $subscribe and $onAction serve different Pinia use cases?

    state-management
  • 34

    What must Pinia account for during server-side rendering?

    ssrstate-management
  • 35

    How should Pinia stores depend on one another without creating cycles?

    state-management
  • 36

    How do global, per-route, and in-component navigation guards differ?

    components
  • 37

    What return values can a Vue Router navigation guard use?

    routingvue
  • 38

    How should route meta fields be used and typed?

  • 39

    How does lazy loading work for Vue Router route components?

    componentsroutingvue
  • 40

    How should a route component react when only its dynamic parameter changes?

    reactcomponents
  • 41

    What are navigation failures in Vue Router?

    routingvue
  • 42

    What does v-memo optimize and what is its trade-off?

    optimization
  • 43

    How does KeepAlive change the lifecycle of dynamic components?

    components
  • 44

    What does defineAsyncComponent add around an asynchronously loaded Vue component?

    componentsvueasync
  • 45

    What problem does Teleport solve in Vue?

    advancedvue
  • 46

    How does Suspense coordinate asynchronous dependencies?

    reactadvancedasync
  • 47

    When is a custom Vue directive appropriate?

    directivesvue
  • 48

    How should a custom directive store per-element state and clean it up?

    directives
  • 49

    How do you type props, defaults, and emitted events in script setup?

    composition-api
  • 50

    How should template refs and child component refs be typed in Vue with TypeScript?

    componentsvuetypescript
  • 51

    How would you design a reusable composable for server-backed search?

    composablesdesign
  • 52

    How would you implement a reusable paginated-data composable?

    composables
  • 53

    How would you structure a composable for a reusable asynchronous form?

    formscomposablesasync
  • 54

    How would you ensure a composable releases watchers, timers, and requests?

    reactivitycomposables
  • 55

    Several components need one cached request result; how would you share it without accidental global state?

    componentscaching
  • 56

    How would you architect a reusable data table with sorting, selection, and custom cells?

    algorithms
  • 57

    How would you implement a modal system that supports several modal types?

    system-design
  • 58

    How would you coordinate a multi-step form built from deeply nested Vue components?

    componentsformsvue
  • 59

    How would you implement an optimistic Pinia update safely?

    state-managementlocking
  • 60

    How would you structure Pinia state for entities reused across several views?

    state-management
  • 61

    How do you decide whether feature state belongs in props, provide and inject, or Pinia?

    state-managementcomponents
  • 62

    How would you compose Pinia stores without creating circular initialization?

    state-management
  • 63

    How would you add persistence to selected Pinia state?

    state-management
  • 64

    How would you prevent stale responses in a debounced Vue search feature?

    debouncevue
  • 65

    A composable loses reactivity after destructuring its input; how would you redesign it?

    reactreactivitycomposables
  • 66

    A third-party editor instance behaves incorrectly after being placed in reactive state; what would you change?

    reactreactivitydependencies
  • 67

    A watcher created after an asynchronous callback keeps running after component unmount; why and how would you fix it?

    componentsreactivityasync
  • 68

    Route changes cause duplicate watcher callbacks in a reused feature; how would you investigate?

    reactivitycallbacks
  • 69

    A watcher creates an infinite update loop; how would you break it?

    reactivity
  • 70

    A computed value stays stale even though related data changes; how would you trace the cause?

    reactivity
  • 71

    A child component updates on every parent render because it receives a newly created object prop; how would you optimize it?

    componentsoptimization
  • 72

    How would you optimize rendering of a list with tens of thousands of rows?

    optimization
  • 73

    How would you decide whether v-memo is appropriate for a slow subtree?

  • 74

    A KeepAlive view shows stale data when users return to it; how would you handle refresh behavior?

  • 75

    How would you introduce async components without creating a poor loading experience?

    componentsasync
  • 76

    How would you profile unnecessary Vue component updates?

    componentsvue
  • 77

    A Nuxt page reports a hydration mismatch; how would you investigate it?

    hydrationnuxtssr
  • 78

    How would you integrate a browser-only chart library into a Nuxt component?

    componentsnuxt
  • 79

    A Nuxt server leaks Pinia state between users; how would you correct the setup?

    composition-apistate-managementnuxt
  • 80

    A Nuxt page fetches the same data on the server and again after hydration; how would you avoid the duplicate request?

    hydrationnuxtssr
  • 81

    A theme from localStorage causes Nuxt hydration differences; how would you design the initial state?

    hydrationnuxtssr
  • 82

    How would you make a Teleport-based modal work with SSR and hydration?

    hydrationssradvanced
  • 83

    How would you implement authentication routing in Nuxt without exposing protected data during SSR?

    ssrnuxtauth
  • 84

    How would you migrate a large Options API component to Composition API incrementally?

    componentscomposition-apioptions-api
  • 85

    How do you translate Options API code that relies heavily on this into Composition API?

    composition-apioptions-apiapi
  • 86

    How would you replace an Options API mixin with composables?

    options-apicomposablesapi
  • 87

    How would you migrate a Vuex module to Pinia?

    state-management
  • 88

    How would you test a reusable Vue component with Vitest and Vue Test Utils?

    componentsvuevitest
  • 89

    How would you test a component that fetches data asynchronously?

    componentsasync
  • 90

    How would you test a composable that uses onMounted and onScopeDispose?

    composables
  • 91

    How would you unit-test a Pinia store?

    hypothesis-testingstate-management
  • 92

    How would you test a Vue component that depends on Vue Router?

    componentsroutingvue
  • 93

    Vue tests break after harmless internal refactoring; how would you improve them?

    refactoringtestingvue
  • 94

    How would you verify that a rendering optimization actually helps?

    optimization
  • 95

    How would you contain errors from one unstable Vue widget?

    vue
  • 96

    How would you test a Suspense-wrapped async component?

    componentsreactadvanced
  • 97

    How would you test a custom directive that integrates an observer?

    directives
  • 98

    How would you structure a large Vue form with conditional sections and autosave?

    formsvue
  • 99

    How would you optimize a slow Vue analytics dashboard?

    vueoptimization
  • 100

    How would you design a route-level Vue feature that includes filters, shared state, SSR data, and tests?

    ssrvuedesign