Vue interview questions test the Composition API, reactivity, directives, components, and composables. Vue interviews tend to focus on how the reactivity system tracks changes and how you'd organize state as an app grows. This page covers 40 real Vue interview questions with answers across four formats: multiple choice, written answers, spoken responses, and live coding challenges, the same mix used in modern technical interviews.
Practice each question in your browser with no signup required. Answers stay hidden until you attempt the question: type, speak, or code your response first, then compare it against the model answer. Questions range from fundamentals for your first developer job to scenario-based questions for senior roles, so you can find the gaps in your knowledge before the real interview.
40 questions with answersLast updated: Oct 19, 2026
Choose a question. Pick any of the 40 questions. They mix multiple choice, written, spoken, and coding, the same mix a real interviewer uses.
Attempt your answer. Select a multiple-choice option, type your written response, record a spoken answer, or write code in the editor.
Reveal the model answer. Once you have attempted the question, the model answer unlocks so you can compare it with yours.
Move to the next question. Track how many questions you have attempted with the progress bar at the top of the page.
Take a mock interview. When you are ready, try a full mock technical interview on Plaicer with AI-driven follow-up questions.
Vue Interview Questions and Answers
0 of 40 attempted
1Multiple choice
How would you describe Vue.js and its primary purpose in web development?
Attempt the question first to reveal the answer.
Answer
Vue.js is a JavaScript framework for building UIs using components, declarative templates, reactive state, and directives.
2Written answer
Explain Vue.js fundamentals including its component model and key architectural concepts
Attempt the question first to reveal the answer.
Answer
Vue.js is a JavaScript framework for building user interfaces using components, which are reusable, independent, and encapsulated pieces of UI. Each component has its own template (HTML), script (logic), and styles. Vue provides reactivity through a dependency-tracking system that updates components when state changes. The framework supports progressive adoption, allowing use on part of a page or as a full application. Key features include declarative templates, directives, component lifecycle, and an ecosystem for routing, state management, and server rendering.
3Spoken answer
Walk through how you would design a reusable modal component that other developers can use across the application
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I'd use props for the open state, emits for close and confirm events, and slots for content. For accessibility, I'd add focus trapping using onMounted and onUnmounted lifecycle hooks to manage focus on open/close. I'd handle Escape key dismissal, lock scroll when modal opens, and set proper ARIA attributes like role='dialog' and aria-label. I'd test keyboard navigation to ensure it's fully accessible. The component should clean up all event listeners in onUnmounted to prevent memory leaks.
4Coding
Create a Vue component that displays a counter with increment and decrement buttons using the Composition API
<template>
<div class="counter">
<!-- Display counter value and add buttons -->
</div>
</template>
<script setup lang="ts">
// Implement counter logic here
</script>
What is the .vue file format and what does it enable?
Attempt the question first to reveal the answer.
Answer
Single-File Components (.vue) keep a component's template, script, and styles together, improving organization in build-tool projects.
6Written answer
Describe the structure and benefits of Single-File Components in build-tool-enabled projects
Attempt the question first to reveal the answer.
Answer
Single-File Components (.vue files) contain a component's template, script, and styles in one file. The structure separates concerns into three sections: template for markup, script for logic, and optional style for scoped CSS. Benefits include keeping related code together, improving maintainability, enabling scoped styling to prevent conflicts, supporting modern tooling like TypeScript and preprocessors, and making components portable and reusable. SFCs are the standard approach in modern Vue projects with build steps.
7Spoken answer
Describe a situation where you chose to use provide/inject instead of props and explain why it was the right choice
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I used provide/inject when building a form with many nested field components. Passing props through every level created prop drilling that made changes difficult. By providing form state and validation functions at the top, child fields accessed what they needed without intermediate components caring. It was cleaner and changes to form logic didn't ripple through the tree. Props would still be used for direct parent-child communication; provide/inject solved the deep nesting problem.
8Coding
Create a component that displays a list of products and filters them based on a search input
How does the Composition API differ in structure from other Vue API styles?
Attempt the question first to reveal the answer.
Answer
The Composition API uses functions like ref(), reactive(), computed(), and watch() to organize component logic.
10Written answer
Compare the Composition API approach with the Options API, discussing tradeoffs for different scenarios
Attempt the question first to reveal the answer.
Answer
The Options API organizes logic into options like data, methods, computed, watch, and lifecycle hooks. It's approachable for simpler components and familiar to developers from other frameworks. The Composition API uses imported functions like ref, reactive, computed, and watch to write logic in any order. It scales better for complex components, provides better code organization for related logic, and enables extraction into reusable composables. Neither is universally better; Options API suits straightforward components while Composition API excels with shared logic and complexity.
11Spoken answer
Explain how you would debug a component that isn't updating when its data changes, even though you believe it should be reactive
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I'd first check if the value is actually reactive by adding a console.log and verifying it changes. Then I'd check for common reactivity breaking patterns: destructuring without toRefs, reassigning ref.value outside reactive scope, or mutating nested object properties. I might be using v-show when I meant v-if, or the dependency might not be declared in computed or watch. I'd also verify the component is actually bound to the data, not showing stale values in the template.
12Coding
Build a component that toggles the visibility of details content when a button is clicked using v-if
<template>
<div class="details">
<button @click="toggleDetails">
{{ showDetails ? 'Hide Details' : 'Show Details' }}
</button>
<div v-if="showDetails" class="content">
<p>This is additional information about the item.</p>
<p>It appears and disappears from the DOM.</p>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const showDetails = ref(false);
function toggleDetails() {
showDetails.value = !showDetails.value;
}
</script>
13Multiple choice
When would you choose v-if over v-show for conditional rendering?
Attempt the question first to reveal the answer.
Answer
v-if unmounts elements from the DOM, reducing render cost initially. Use it when conditions change rarely.
14Written answer
Explain how ref() works and when you would use it for reactive values
Attempt the question first to reveal the answer.
Answer
ref() creates a reactive wrapper around a value. In templates, refs are automatically unwrapped; in scripts, access the value via .value property. Use ref() for primitive values (strings, numbers, booleans) and when a value might be replaced entirely. Unlike reactive(), which wraps objects, ref() works for any type and supports complete reassignment. Example: const count = ref(0); count.value += 1 updates the reactive value.
15Spoken answer
Talk about a time you optimized a Vue component or list that was rendering slowly and what techniques you applied
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I profiled the component and found rendering thousands of rows in a list was the bottleneck. I implemented virtual scrolling to render only visible rows, reducing DOM nodes dramatically. I also moved expensive calculations to computed properties instead of template expressions. I added stable keys to prevent state loss when filtering. For large immutable datasets, I used shallowRef to avoid deep reactivity overhead. These changes made the list interactive even with large datasets.
16Coding
Create a dropdown component that displays a list of menu options when clicked and emits the selected option
<template>
<div class="dropdown">
<button @click="toggleMenu">{{ selectedOption || 'Select an option' }}</button>
<!-- Render menu items when open -->
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const isOpen = ref(false);
const selectedOption = ref(null);
const options = ['Option A', 'Option B', 'Option C'];
const emit = defineEmits<{
select: [option: string];
}>();
// Add logic here
</script>
What role do keys play when rendering lists that can change?
Attempt the question first to reveal the answer.
Answer
Stable keys help Vue maintain component state across list changes. Index keys can cause state to persist on wrong rows.
18Written answer
Describe reactive() and explain the pitfall when destructuring reactive objects
Attempt the question first to reveal the answer.
Answer
reactive() creates a reactive proxy for objects. Modifications to object properties trigger reactivity. The pitfall occurs when destructuring because destructuring breaks reactivity: const { email } = form gives you the current value but not a reactive binding. To preserve reactivity when destructuring, use toRefs(): const { email } = toRefs(form) creates reactive bindings. This is a common source of 'why isn't my template updating?' bugs.
19Spoken answer
Describe how you would approach organizing components, composables, and stores in a large Vue application to keep it maintainable
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I organize by feature when features are substantial: each feature gets a folder with route, components, composables, store (if needed), and API client. Shared UI lives in a shared components folder. Utilities and helpers go in a common folder. This structure scales; features can be developed independently. I avoid a monolithic components folder with hundreds of one-offs. Types go alongside code that uses them. Each section is clear about what it owns.
20Coding
Create a component that displays items with prices and uses a computed property to calculate the total
Describe the flow of data when using props between parent and child components
Attempt the question first to reveal the answer.
Answer
Props pass data from parent to child. Children should emit events to request changes, not mutate props.
22Written answer
Distinguish between computed and watch, explaining when to use each
Attempt the question first to reveal the answer.
Answer
computed() creates derived values calculated from reactive state, used during render. It's ideal for formatting, filtering, or transforming data. computed() is cached and only recalculates when dependencies change. watch() handles side effects when reactive values change, like API calls, storage sync, logging, or bridging to non-Vue code. Use computed when you can calculate during render; use watch for side effects that shouldn't run every render. If you can calculate it, use computed.
23Spoken answer
Explain how you would handle form validation in Vue, including display of error messages and preventing submission when invalid
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I keep form state in a reactive object and a separate errors object keyed by field. Each field validates on blur rather than every keystroke, so the user isn't corrected mid-word. A computed isValid checks the errors object is empty. The submit handler runs validateAll first and returns early if anything fails, and the button is disabled while isValid is false. Errors render inline under the field with aria-describedby so screen readers announce them. For more than a couple of forms I'd use VeeValidate with a Zod or Yup schema so the rules live in one place and the server can reuse them.
24Coding
Build a component with an email input that validates the format and displays error messages
How does v-model create a two-way binding convention in Vue components?
Attempt the question first to reveal the answer.
Answer
v-model on a component is a convention using a prop and update event, useful for form-like components.
26Written answer
Explain Vue's dependency tracking system and how reactivity updates components
Attempt the question first to reveal the answer.
Answer
Vue tracks reactive reads during rendering and effect execution, recording which values were accessed. When tracked reactive values change, Vue updates the affected parts without rerendering everything. Vue 3 uses JavaScript proxies for object reactivity and ref wrappers for individual values. The system automatically establishes dependencies without manual declaration. This fine-grained reactivity means only components that depend on changed data update, not the entire app.
27Spoken answer
Walk through how you would implement a feature where URL filters sync with component state so users can bookmark results
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
The URL is the source of truth, not the component. On mount I read route.query and initialise filter state from it, with defaults for anything missing. When a filter changes I call router.replace with the new query rather than push, so every tweak doesn't add a history entry. A watcher on route.query syncs state the other way for back and forward navigation. Arrays serialise as comma-separated strings and numbers get parsed back, since everything in the query arrives as a string. Because state derives from the URL, a bookmarked or shared link reproduces the exact view, and the results fetch is a watch on the parsed query.
28Coding
Create a component that toggles a CSS class on an element based on a button click
<template>
<div>
<button @click="toggleActive">Toggle Style</button>
<!-- Apply active class conditionally -->
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
// Add logic here
</script>
<style scoped>
.active {
background-color: green;
color: white;
}
</style>
Explain how slots enable content composition in Vue components
Attempt the question first to reveal the answer.
Answer
Slots allow parents to pass template content to children. Useful for layout, cards, modals, and reusable shells.
30Written answer
Define composables and discuss how they encapsulate reusable stateful logic
Attempt the question first to reveal the answer.
Answer
Composables are functions combining Composition API features to package reusable stateful logic. They use ref, reactive, computed, watch, and lifecycle hooks to create self-contained, portable units of functionality. Good composables clean up side effects in onUnmounted, have small APIs, and handle their own state. Example: useWindowWidth() manages window resize listeners and exposes a reactive width value. Composables replace mixins for better code reuse with clearer dependencies.
31Spoken answer
Describe how you would set up a composable that handles loading, error, and retry logic for API requests
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I write a useRequest composable that takes a fetcher function and returns data, error, isLoading and an execute method, all as refs so the template stays reactive. Execute sets isLoading true, clears the previous error, awaits the fetcher, and catches any failure into error. Retry is execute with an attempt counter and exponential backoff, capped at three tries, and I only retry on network or 5xx errors, never on 4xx. An AbortController cancels the in-flight request if the component unmounts or execute is called again. Keeping it generic means every list and detail view shares the same loading and error UI with no copy-pasted try/catch.
32Coding
Create a component that allows adding new todos and marking them as completed
<template>
<div class="todos">
<input v-model="newTodo" @keyup.enter="addTodo" placeholder="Add a todo" />
<!-- Display todos with completion toggle -->
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
// Add todo logic here
</script>
When should you use provide/inject versus props for passing data?
Attempt the question first to reveal the answer.
Answer
Use provide/inject for shared context like theme or form state. Use props for direct parent-child communication.
34Written answer
Describe the pattern for managing loading, success, error, and empty states when fetching data
Attempt the question first to reveal the answer.
Answer
Separate request state into distinct properties: loading (boolean), data (result when successful), error (error message), and empty (no results). Fetch data when routes load or inputs change. Model the flow: initial loading state, transition to success/error/empty based on result. Always show one state to users: loading spinner, data, error message with retry option, or empty state message. In SSR or framework setups, prefer the framework's data-loading pattern over component-level fetching.
35Spoken answer
Explain how you would teach a junior developer the difference between Composition API and Options API to help them choose the right approach
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I'd start with one small component written both ways. Options API groups code by kind — data, computed, methods — which is easy to scan while the component is small. Composition API groups code by feature inside setup, so a search feature's state, computed and handlers sit together. The turning point is when a component grows past a few features: with Options you scroll between sections to follow one feature, with Composition you don't. Then I'd show extracting that feature into a composable, which Options can't do cleanly. My rule for them: Options for a quick, small component in a legacy codebase; Composition for anything new, anything shared, or anything in TypeScript.
36Coding
Create a component that displays product prices formatted as currency using a computed property
How do composables package and reuse stateful logic in Vue?
Attempt the question first to reveal the answer.
Answer
Composables are functions combining Vue API features like ref, watch, and lifecycle hooks for reusable logic.
38Written answer
Explain which state should go in the URL versus stay as local component state
Attempt the question first to reveal the answer.
Answer
Put shareable, bookmarkable state in the URL: search queries, filters, sort order, page numbers, selected tabs where back-button behavior is expected. Keep ephemeral UI state local: open menus, draft form input, hover state, temporary loading flags. This distinction lets users bookmark and share URLs representing the exact view they see. Local state avoids polluting the URL bar and stays easier to reason about since only the component owns it.
39Spoken answer
Talk about managing component communication in a scenario where deeply nested children need to notify distant ancestors about state changes
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
Props down and emits up works for one or two levels, but chaining emits through five components means every layer in between knows about an event it doesn't care about. For a distant ancestor I use provide and inject: the ancestor provides a reactive object or a callback, the deep child injects it and calls it directly, and the middle layers stay clean. If the state is shared by unrelated branches of the tree, or needs to survive navigation, it belongs in a Pinia store instead — the child writes to the store, the ancestor watches it. I avoid an event bus; it hides the data flow and is hard to trace in DevTools.
40Coding
Build a button component that emits a custom event with data when clicked
<template>
<button @click="handleClick">
Click Me
</button>
</template>
<script setup lang="ts">
const emit = defineEmits<{
myEvent: [message: string];
}>();
function handleClick() {
// Emit event with data
}
</script>
Attempt the question first to reveal the answer.
Answer
<template>
<button @click="handleClick">
Click Me
</button>
</template>
<script setup lang="ts">
const emit = defineEmits<{
myEvent: [message: string];
}>();
function handleClick() {
emit('myEvent', 'Button was clicked!');
}
</script>
Directives: v-if vs v-show, v-for and keys, v-model
Component communication: props, emits, slots
Provide and inject
Composables: reusable logic, loading and error states
Forms and validation
App structure: organizing large apps, URL vs local state
Frequently asked questions
How many Vue interview questions are on this page?
40 real Vue interview questions across four formats: multiple choice (10), written answer (10), spoken answer (10), and coding (10).
Do I need to sign up to practice?
No. All 40 questions and model answers are free with no signup. You attempt each question first, and the model answer unlocks once you have engaged.
Who are these Vue interview questions for?
Developers preparing for Vue technical interviews at any level, from first job to senior engineer roles. Questions cover fundamentals through real-world scenarios.
What topics do the Vue questions cover?
The questions cover single-file components, the Composition and Options APIs, and reactivity with ref and reactive. They also test computed properties, watchers, and directives. Other topics include component communication, provide and inject, composables, and forms.
Can I practice coding questions in the browser?
Yes. Coding questions include starter code in an in-browser editor, so you can write your solution without installing anything.
How often are the questions updated?
The question bank is reviewed regularly and updated to reflect current Vue interview patterns.
Can I take a full mock interview?
Yes. Plaicer's mock technical interview walks you through a realistic 30 to 45 minute interview with AI-driven follow-up questions.
Do the questions cover Vue 2 or Vue 3?
Vue 3, with a focus on the Composition API. A few questions compare it with the Options API, since interviews still ask about both.