Ace your Vue.js interview with 45+ questions covering Vue 3, Composition API, Pinia state management, and performance patterns.
Options API organizes code by option type (data, methods, computed, watch) — familiar for beginners but scatters related logic. Composition API organizes by feature using setup() — keeps related logic together, enables code reuse via composables, better TypeScript support. Vue 3 supports both; use Composition API for new projects. Options API components can live alongside Composition API components.
Vue compiles templates to render functions at build time. Render function creates virtual DOM (VNode tree). On state change, Vue re-runs render function, diffs new VNode tree against previous, patches only changed DOM nodes. Vue 3 introduces block tree optimization — tracks only dynamic nodes, skipping static content. Compiler marks static nodes for hoisting, further reducing diff cost.
Teleport renders content in a different DOM location (like React portals). Syntax: <Teleport to="body">...</Teleport>. Use for: modals, tooltips, notifications that need to escape parent's overflow/z-index. The component remains in the Vue tree (events, context work normally) but renders at the target DOM node. Multiple teleports to same target are appended in order.
ref() wraps any value (primitives and objects), access via .value. reactive() creates a deeply reactive object proxy — no .value needed. Use ref for primitives (numbers, strings, booleans) and single values. Use reactive for complex objects you want direct property access. Tip: ref is more flexible — it can be destructured without losing reactivity when using toRefs().
Computed: derived value, cached until dependencies change, read-only by default (can be writable with get/set), returns value. Watcher: reacts to source change to perform side effects (API calls, DOM manipulation), can be async. Use computed for derived state. Use watch for side effects triggered by state changes. watchEffect auto-tracks dependencies; watch is explicit. Avoid watchers when computed suffices.
Composables are functions that use Vue Composition API internally and return reactive state/methods. Like React hooks. Replace mixins because: no naming conflicts, clear data source (explicit return), no implicit merge. Example: useFetch() encapsulates data, loading, error state. Use for: shared state logic, API calls, browser APIs. Naming convention: use prefix.
provide() makes data available to all descendants without prop drilling. inject() reads the provided value. Works with reactivity (provide a ref, inject gets reactive value). Use for: global config, theming, deeply nested data passing, plugin systems. Differs from Pinia: provide/inject is component-tree-scoped, not global. Don't overuse — Pinia is better for true global state.
Setup phase: setup() runs first, before any lifecycle hooks. Mounting: onBeforeMount → onMounted (DOM available). Updating: onBeforeUpdate → onUpdated. Unmounting: onBeforeUnmount → onUnmounted (clean up listeners, timers). Also: onErrorCaptured, onActivated/Deactivated (keep-alive). In Options API: beforeCreate, created, beforeMount, mounted, etc. Use onMounted for DOM manipulation, onUnmounted for cleanup.
Pinia is Vue 3's official state management library (Vuex successor). Advantages: no mutations (direct state changes), better TypeScript support, modular by default, devtools support, composable stores. Vuex requires mutations for changes; Pinia uses actions/direct assignment. Pinia stores are plain composables — you can use them outside Vue components. Smaller bundle too.
v-model is shorthand for :modelValue + @update:modelValue. On input: :value + @input. With custom components: define modelValue prop and emit update:modelValue. Vue 3 supports multiple v-model bindings (v-model:title, v-model:content). Use defineModel() macro in Vue 3.4+ for cleaner implementation. Modifiers: .lazy (change event), .number (cast), .trim (whitespace).
Directives are DOM manipulation instructions: v-if, v-show, v-for, v-bind, v-on, v-model, v-slot. Create custom: app.directive("focus", { mounted(el) { el.focus() } }). Directive hooks: created, beforeMount, mounted, beforeUpdate, updated, beforeUnmount, unmounted. Receive: el (DOM), binding (value, arg, modifiers), vnode. Use for: focus management, intersection observers, tooltips, permissions.
Strategies: (1) v-memo for expensive list items, (2) shallowRef/shallowReactive to limit reactivity depth, (3) defineAsyncComponent for code splitting, (4) v-show vs v-if (show for frequent toggles), (5) Avoid expensive computed in v-for, (6) Use :key properly, (7) Virtualize long lists (vue-virtual-scroller), (8) Keep components small and focused, (9) Bundle analysis with rollup-plugin-visualizer.
Nuxt.js is the Vue SSR/SSG framework. Modes: SSR (server renders on each request), SSG (pre-rendered at build, static files), SPA mode. Data fetching: useAsyncData (SSR-aware), useFetch (wrapper around useAsyncData). Auto-imports composables and components. File-based routing. Plugins for shared code. Use for: SEO, initial load performance, social sharing. Nuxt 3 is built on Vue 3 + Vite.
Vue's Suspense displays fallback content while async components or async setup() resolve. Wrap with <Suspense><template #default>...</template><template #fallback>Loading...</template></Suspense>. Works with defineAsyncComponent and components with async setup(). Can nest Suspense boundaries. Use onErrorCaptured or <ErrorBoundary> to handle errors within Suspense.
Vue <Transition> applies CSS classes when elements enter/leave: v-enter-from, v-enter-active, v-enter-to (and leave equivalents). <TransitionGroup> for lists. Use with CSS transitions/animations or JavaScript hooks. Name prop sets prefix (name="fade" → fade-enter-from). Combine with animation libraries: @vueuse/motion, GSAP. <Transition mode="out-in"> for component switching.
Practice with interactive quizzes and get instant feedback.
Start Free Practice