Home Interview Vue.js Interview Questions: Top 30+ with Answers for 2025
Intermediate 3 min · July 13, 2026

Vue.js Interview Questions: Top 30+ with Answers for 2025

Prepare for your Vue.js interview with 30+ common questions covering reactivity, lifecycle, Vuex, Vue Router, composition API, and more.

N
Naren Founder & Principal Engineer

20+ years shipping production code across the stack, with years spent interviewing engineers. Drawn from code that ran under real load.

Follow
Production
production tested
July 13, 2026
last updated
2,165
articles · all by Naren
Before you start⏱ 20-25 min read
  • Basic knowledge of HTML, CSS, and JavaScript
  • Familiarity with ES6 features (arrow functions, modules, etc.)
  • Understanding of single-page application concepts
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Understand Vue's reactivity system and how it tracks dependencies.
  • Know the component lifecycle hooks and their order.
  • Be able to explain Vuex state management and Vue Router navigation guards.
  • Master the Composition API and when to use it over Options API.
  • Practice common coding problems like implementing a custom directive or a reactive state manager.
✦ Definition~90s read
What is Vue.js Interview Questions?

Vue.js is a progressive JavaScript framework for building user interfaces, known for its reactivity system and component-based architecture.

Imagine you're building a house.
Plain-English First

Imagine you're building a house. Vue.js is like a smart blueprint that automatically updates the paint color on the walls when you change your mind about the color. You don't have to repaint every room manually; Vue does it for you. Interviewers want to know if you understand how this magic works under the hood.

⚙ Browser compatibility
Latest versions — ✓ supported
ChromeFirefoxSafariEdge

Vue.js has become one of the most popular JavaScript frameworks for building user interfaces. Its gentle learning curve, combined with powerful features like reactivity, component-based architecture, and a rich ecosystem, makes it a favorite among developers and companies alike. Whether you're applying for a frontend role at a startup or a tech giant, Vue.js interview questions are a staple.

This guide covers the most frequently asked Vue.js interview questions, from fundamental concepts to advanced topics. Each question includes a clear answer, code examples, and tips on how to present your knowledge during an interview. We also dive into real-world scenarios, common mistakes, and debugging techniques to help you stand out.

By the end of this article, you'll be equipped to answer questions on reactivity, lifecycle hooks, Vuex, Vue Router, the Composition API, and more. Let's get started!

1. Vue.js Reactivity System

Vue's reactivity system is the core that makes the framework so intuitive. In Vue 2, it uses Object.defineProperty to intercept getters and setters. In Vue 3, it uses the Proxy API, which allows for more comprehensive reactivity, including property addition and deletion.

How it works: When you define a data property, Vue converts it into a reactive property. During the component's render, it tracks which properties are accessed (dependencies). When a property changes, Vue re-renders only the components that depend on it.

Interview Tip: Explain the difference between Vue 2 and Vue 3 reactivity. Mention that Vue 2 cannot detect property addition/deletion, while Vue 3 can. Also, note that Vue 3's reactivity system is more performant because it doesn't need to recursively traverse the object at initialization.

reactivity.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Vue 2: Object.defineProperty
var vm = new Vue({
  data: {
    message: 'Hello'
  }
})
// This works
vm.message = 'World'
// This does NOT trigger reactivity in Vue 2
vm.newProp = 'New' // Not reactive

// Vue 3: Proxy
const state = reactive({
  message: 'Hello'
})
state.message = 'World' // Reactive
state.newProp = 'New' // Also reactive!
Output
// No output, but the reactivity works differently.
Try it live
🔥Reactivity Caveats
📊 Production Insight
A common production bug is when a developer adds a property to a reactive object directly in Vue 2, causing the UI to not update. Always use Vue.set or the spread operator.
🎯 Key Takeaway
Understanding reactivity is crucial for debugging and optimizing Vue apps. Know the differences between Vue 2 and Vue 3.

2. Component Lifecycle Hooks

Vue components go through a series of lifecycle stages: creation, mounting, updating, and destruction. Each stage has hooks that allow you to run code at specific times.

Order of hooks: 1. beforeCreate - data and events not yet set up 2. created - data and events available, but DOM not mounted 3. beforeMount - just before mounting 4. mounted - component mounted to DOM 5. beforeUpdate - before DOM update 6. updated - after DOM update 7. beforeUnmount (Vue 3) / beforeDestroy (Vue 2) - before teardown 8. unmounted (Vue 3) / destroyed (Vue 2) - after teardown

Interview Tip: Be able to explain when to use each hook. For example, API calls go in mounted, cleanup in beforeUnmount. Also, note that created is often used for initial data setup, but DOM access is only possible in mounted.

lifecycle.vueJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello'
    }
  },
  beforeCreate() {
    console.log('beforeCreate: data not ready', this.message) // undefined
  },
  created() {
    console.log('created: data ready', this.message) // 'Hello'
  },
  mounted() {
    console.log('mounted: DOM ready')
  },
  beforeUnmount() {
    console.log('beforeUnmount: cleanup')
  }
}
</script>
Output
// Console output:
// beforeCreate: data not ready undefined
// created: data ready Hello
// mounted: DOM ready
Try it live
💡Lifecycle in Composition API
📊 Production Insight
A common mistake is making API calls in created and not handling component unmount before the response arrives. Use an abort controller or a flag to avoid updating unmounted components.
🎯 Key Takeaway
Lifecycle hooks are essential for managing side effects. Always clean up in beforeUnmount to prevent memory leaks.

3. Vuex State Management

Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all components, with rules ensuring that the state can only be mutated in a predictable fashion.

Core concepts: - State: single source of truth - Getters: computed properties for the store - Mutations: synchronous functions that modify state - Actions: asynchronous functions that commit mutations - Modules: organize the store into smaller pieces

Interview Tip: Explain why we need mutations to be synchronous and actions to be asynchronous. Mutations are synchronous so that Devtools can capture a snapshot of the state before and after the mutation. Actions can contain arbitrary asynchronous operations.

store.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { createStore } from 'vuex'

export default createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment')
      }, 1000)
    }
  },
  getters: {
    doubleCount(state) {
      return state.count * 2
    }
  }
})
Output
// No direct output, but the store is used in components.
Try it live
⚠ Vuex vs Pinia
📊 Production Insight
A common issue is forgetting to use namespaced modules, leading to name collisions. Always namespace your modules if you have multiple.
🎯 Key Takeaway
Vuex enforces a unidirectional data flow. Actions handle async, mutations change state, and getters derive data.

4. Vue Router and Navigation Guards

Vue Router is the official router for Vue.js. It allows you to map components to routes and control navigation with guards.

Types of guards: - Global guards: beforeEach, beforeResolve, afterEach - Per-route guards: beforeEnter - In-component guards: beforeRouteEnter, beforeRouteUpdate, beforeRouteLeave

Interview Tip: Explain how to protect routes (e.g., authentication). Use beforeEach to check if the user is logged in and redirect to login if not. Also, note that beforeRouteEnter does not have access to this because the component hasn't been created yet; you can pass a callback to next.

router.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { createRouter, createWebHistory } from 'vue-router'
import Home from './views/Home.vue'
import Dashboard from './views/Dashboard.vue'

const routes = [
  { path: '/', component: Home },
  { 
    path: '/dashboard', 
    component: Dashboard,
    beforeEnter: (to, from, next) => {
      const isAuthenticated = localStorage.getItem('token')
      if (!isAuthenticated) {
        next('/login')
      } else {
        next()
      }
    }
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router
Output
// No output, but the router guards control navigation.
Try it live
🔥Navigation Guard Pitfalls
📊 Production Insight
A common bug is using beforeRouteEnter to fetch data but not handling the case where the component is reused (same route, different params). Use beforeRouteUpdate instead.
🎯 Key Takeaway
Navigation guards are powerful for authentication, authorization, and data fetching. Use them wisely to control user flow.

5. Composition API vs Options API

Vue 3 introduced the Composition API as an alternative to the Options API. It allows you to organize component logic by feature rather than by option type.

Options API: - Data, computed, methods, watch, lifecycle hooks are separate options. - Logic for a single feature can be spread across multiple options. - Easier for beginners.

Composition API: - Uses setup() function where you define reactive state, computed properties, and functions. - Logic can be extracted into reusable composables. - Better TypeScript support.

Interview Tip: Discuss when to use each. For simple components, Options API is fine. For complex components with multiple features, Composition API improves readability and reusability.

composition.vueJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">+</button>
  </div>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    function increment() {
      count.value++
    }
    return { count, increment }
  }
}
</script>
Output
// Renders a counter that increments on button click.
Try it live
💡Composables: The Power of Composition API
📊 Production Insight
A common mistake is mixing Options API and Composition API in the same component. Stick to one pattern per component for consistency.
🎯 Key Takeaway
Composition API is more flexible and scalable for large applications. It's the recommended approach for Vue 3.

6. Custom Directives and Filters

Custom directives allow you to reuse DOM manipulation logic. Filters (removed in Vue 3) were used for text formatting.

Creating a custom directive: - Global: app.directive('focus', {...}) - Local: directives: { focus: {...} }

Directive hooks: created, mounted, updated, unmounted.

Interview Tip: Give an example of a custom directive, like v-focus that auto-focuses an input. Also, mention that filters are replaced by computed properties or methods in Vue 3.

directive.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Global directive
app.directive('focus', {
  mounted(el) {
    el.focus()
  }
})

// Usage: <input v-focus />

// Local directive
export default {
  directives: {
    highlight: {
      mounted(el) {
        el.style.backgroundColor = 'yellow'
      }
    }
  }
}
Output
// The input gets focused automatically when mounted.
Try it live
🔥Filters in Vue 3
📊 Production Insight
Overusing custom directives can make code harder to maintain. Always consider if a component or composable could achieve the same goal.
🎯 Key Takeaway
Custom directives are useful for low-level DOM access. Use them sparingly and prefer built-in directives when possible.

7. Performance Optimization Techniques

  • Virtual scrolling for large lists (e.g., using vue-virtual-scroller).
  • Lazy loading routes with dynamic imports.
  • Computed properties vs methods: computed are cached based on dependencies.
  • v-once directive to render static content once.
  • v-memo (Vue 3.2+) to memoize a template subtree.
  • Functional components (Vue 2) or using render functions for performance-critical parts.

Interview Tip: Explain the difference between v-if and v-show. v-if removes the element from DOM, v-show toggles visibility with CSS. Use v-if for infrequent toggles, v-show for frequent toggles.

performance.vueJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<template>
  <div>
    <!-- v-once: renders only once -->
    <p v-once>{{ staticMessage }}</p>
    
    <!-- v-memo: memoizes based on dependencies -->
    <div v-memo="[item.id]">
      {{ item.name }}
    </div>
    
    <!-- Lazy load component -->
    <component :is="lazyComponent" />
  </div>
</template>

<script>
import { defineAsyncComponent } from 'vue'

export default {
  data() {
    return {
      staticMessage: 'This will not change',
      item: { id: 1, name: 'Item' }
    }
  },
  components: {
    lazyComponent: defineAsyncComponent(() =>
      import('./HeavyComponent.vue')
    )
  }
}
</script>
Output
// Static message renders once, heavy component loads lazily.
Try it live
⚠ Premature Optimization
📊 Production Insight
A common performance issue is using methods in templates that return new objects each render, causing unnecessary re-renders. Use computed properties instead.
🎯 Key Takeaway
Optimize only when needed. Use computed properties, lazy loading, and virtual scrolling for large datasets.

8. Testing Vue Components

Testing is crucial for production apps. Common testing approaches:

  • Unit testing with Jest or Vitest + Vue Test Utils.
  • Component testing with @vue/test-utils.
  • End-to-end testing with Cypress or Playwright.

Interview Tip: Explain how to test a component that uses Vuex or Vue Router. Use createStore and createRouter in tests. Also, mention that you can mock dependencies.

test.spec.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
import { mount } from '@vue/test-utils'
import Counter from './Counter.vue'

describe('Counter.vue', () => {
  it('increments count when button is clicked', async () => {
    const wrapper = mount(Counter)
    const button = wrapper.find('button')
    await button.trigger('click')
    expect(wrapper.text()).toContain('1')
  })
})
Output
// Test passes if the counter increments correctly.
Try it live
💡Testing Async Behavior
📊 Production Insight
A common mistake is testing implementation details instead of behavior. Focus on what the user sees and interacts with.
🎯 Key Takeaway
Testing gives confidence in your code. Write tests for critical components and user flows.
● Production incidentPOST-MORTEMseverity: high

The Case of the Vanishing User Data: A Vue Reactivity Bug

Symptom
Users reported that after editing a profile field, the page became unresponsive and sometimes showed stale data.
Assumption
The developer assumed that adding a new property to a reactive object would automatically trigger a re-render.
Root cause
Vue 2's reactivity system cannot detect property addition or deletion. The developer used this.user.newField = value instead of Vue.set(this.user, 'newField', value).
Fix
Replaced direct assignment with Vue.set or used the spread operator to create a new object. In Vue 3, the issue is mitigated by Proxy-based reactivity.
Key lesson
  • Always use Vue.set (Vue 2) or reassign the entire object (Vue 3) when adding new properties to reactive objects.
  • Understand the limitations of the framework you're using.
  • Use linters and TypeScript to catch such issues early.
  • Write unit tests that cover data mutations.
  • Monitor performance with Vue Devtools to detect unexpected re-renders.
Production debug guideSymptom to Action4 entries
Symptom · 01
UI not updating after data change
Fix
Check if the property was added reactively (use Vue.set in Vue 2 or reassign in Vue 3). Use Vue Devtools to inspect the component's reactive state.
Symptom · 02
Component re-renders too often
Fix
Add a key attribute to v-for loops. Use computed properties instead of methods in templates. Check for unnecessary watchers.
Symptom · 03
Route change not triggering component update
Fix
Ensure you are using watch on $route or the beforeRouteUpdate guard. Check if the component is reused (same route with different params).
Symptom · 04
Vuex state mutation not reflected in component
Fix
Verify that the mutation is committed correctly. Check if the component is using mapState or mapGetters with the correct namespace. Ensure the component is still mounted.
★ Quick Debug Cheat Sheet for Vue.jsCommon symptoms and immediate actions to diagnose Vue.js issues.
Data change not reflected in DOM
Immediate action
Check if property was added after creation (Vue 2).
Commands
console.log(this.$data)
Vue.set(this.obj, 'key', value)
Fix now
Use Vue.set or replace the object.
Component not updating on route change+
Immediate action
Add a watch on $route.
Commands
watch: { '$route'(to, from) { ... } }
console.log('route changed')
Fix now
Use beforeRouteUpdate or key on <router-view>.
Vuex state not reactive+
Immediate action
Check if mutation is synchronous.
Commands
console.log(store.state)
store.commit('mutationName')
Fix now
Ensure mutations are synchronous and use Vue.set for new properties.
Computed property not updating+
Immediate action
Check dependencies for reactivity.
Commands
console.log(this.computedProperty)
console.log(this.dependency)
Fix now
Ensure all dependencies are reactive and not mutated outside Vue.
FeatureVue 2Vue 3
ReactivityObject.definePropertyProxy
Property additionNot reactive (use Vue.set)Reactive automatically
API styleOptions APIOptions + Composition API
TypeScript supportLimitedFirst-class
PerformanceGoodBetter (smaller bundle, faster updates)
State managementVuexPinia (recommended)
⚙ Quick Reference
8 commands from this guide
FileCommand / CodePurpose
reactivity.jsvar vm = new Vue({1. Vue.js Reactivity System
lifecycle.vue