Vue.js Interview Questions and Answers

Reactivity, the Composition API, directives and the Vue ecosystem.

Practise 10 random 251 peer-reviewed questions
Vue.js Interview Syllabus & Preparation Strategy

Whether you are preparing for entry-level Vue.js interview questions for freshers or senior software engineer interview questions addressing concurrency, scalability, and system architecture, this track provides peer-reviewed model answers with syntax walkthroughs, edge cases, and practical interview tips.

1 What is the difference between the Options API and the Composition API in Vue 3? Easy

The Options API organises component logic into fixed options such as data, methods, computed, watch and lifecycle hooks. The Composition API organises the same logic inside setup() using functions imported from vue.

// Options API
export default {
  data: () => ({ count: 0 }),
  methods: { inc() { this.count++; } },
};
// Composition API
const count = ref(0);
const inc = () => count.value++;

Trade-offs: the Composition API makes stateful logic easier to extract as composables, gives simpler TypeScript inference, and keeps related logic together instead of splitting it across option blocks. The Options API remains approachable for small components and has a gentler learning curve.

Both compile to the same runtime and can be mixed via setup(). Most large Vue 3 codebases prefer the Composition API for maintainability, while teams migrating from Vue 2 often keep the Options API for simple views.

2 When should you use v-if instead of v-show? Easy

v-if conditionally renders: when the expression is falsy the element and its children are not created, and they are destroyed when it flips. It supports v-else and v-else-if and can be applied to a template.

v-show always renders the element and only toggles display: none through inline CSS. Because of that it is cheaper for frequent toggling, with no create, destroy or diffing cost, but it has a higher initial render cost and cannot be used on template or with v-else.

Use v-if when the condition rarely changes or the subtree is expensive to keep mounted. Use v-show when something toggles often, such as a dropdown or a tab panel, because the DOM stays put.

Note that v-if has higher priority than v-for in Vue 3, so placing them on the same element is discouraged; filter the list in a computed instead. Neither directive preserves component state across hiding unless you wrap the subtree in KeepAlive.

3 What is Vue.js? Easy

Vue.js is an open-source, progressive Javascript framework for building user interfaces that aim to be
incrementally adoptable. The core library of VueJS is focused on the view layer only, and is easy to pick up and
integrate with other libraries or existing projects.

****

4 What is Vue instance? Easy

Every Vue application works by creating a new Vue instance with the Vue function. Generally the variable vm (short
for ViewModel) is used to refer Vue instance. You can create vue instance as below,

var vm = new Vue({
  // options
})

As mentioned in the above code snippets, you need to pass options object. You can find the full list of options in
the API reference.

****

5 How do you use v-for directive with a range? Easy

You can also use integer type(say 'n') for v-for directive which repeats the element many times.

<div>
  <span v-for="n in 20">{{ n }} </span>
</div>

It displays the number 1 to 20.

****

6 How do you use v-for directive on template? Easy

Just similar to v-if directive on template, you can also use a <template> tag with v-for directive to render a
block of multiple elements.

Let's take a todo example,

<ul>
  <template v-for="todo in todos">
    <li>{{ todo.title }}</li>
    <li class="divider"></li>
  </template>
</ul>

****

7 What is vuex? Easy

Vuex is a state management pattern + library (Flux-inspired Application Architecture) for Vue.js applications. It
serves as a centralized store for all the components in an application, with rules ensuring that the state can only
be mutated in a predictable fashion.

****

8 What is Vue CLI? Easy

Vue CLI is a simple command line interface for scaffolding Vue.js projects. It will be helpful for rapid Vue.js
development. You can install the npm package globally as below,

npm install -g @vue/cli
# OR
yarn global add @vue/cli

You can find the install version using vue --version command.
Note: Vue CLI requires Node.js version 8.9 or above (8.11.0+ recommended).

****

9 What is vuetify? Easy

Vuetify is a semantic component material framework for Vue. It aims to provide clean, semantic and reusable
components that make building application easier. The installation and configuration is simple as below,

npm install Vuetify
import Vue from 'vue'
import Vuetify from 'vuetify' // Import Vuetify to your project

Vue.use(Vuetify) // Add Vuetify as a plugin

****

10 How does reactivity work in Vue 3 with Proxy? Medium

Vue 3 wraps reactive objects in an ES Proxy that intercepts get and set operations. On a get, track() records the currently active effect (a render function, computed or watcher) into a dependency map keyed by the target and property. On a set, trigger() looks up that map and re-runs the dependent effects.

const state = reactive({ count: 0 });
effect(() => console.log(state.count));
state.count++; // get, then set -> effect re-runs

Because the Proxy is lazy, nested objects are only wrapped when accessed, keeping initialisation cheap. ref() stores a value in a .value property and uses the same tracking internally, so primitives work too. Effects are batched into a microtask queue, so several synchronous mutations produce a single update.

Caveats: proxies cannot detect property additions on a raw object if you bypass the wrapper, reassigning a ref replaces its value, and markRaw or shallowRef skip deep conversion. This design is why Vue 3 tracks added and deleted keys correctly, unlike Vue 2's Object.defineProperty approach.

11 Explain the difference between computed, watch and watchEffect. Medium

computed derives a cached value from reactive dependencies. The getter re-evaluates only when a dependency changes and something reads the value, which makes it ideal for derived state used in templates. It must be pure.

watch runs a side effect when a specific source changes. It is lazy by default, gives you old and new values, supports deep, immediate and a cleanup callback, and is the right tool for data fetching or imperative work.

watchEffect runs immediately and automatically tracks every reactive property read during execution, re-running when any of them change. It is concise but makes dependencies implicit.

const total = computed(() => items.value.reduce((s, i) => s + i.price, 0));
watch(total, (v, old) => console.log(v, old));
watchEffect(() => console.log(total.value));

Never mutate state inside computed; use watch for side effects. Prefer computed over a method in a template to gain caching, and call the returned watcher handle to stop it when needed.

12 What is the difference between ref and reactive, and what are the pitfalls? Medium

ref creates a reactive reference that can hold any value, including primitives, and is accessed through .value in JavaScript while auto-unwrapping in templates. reactive returns a Proxy for an object and lets you access properties directly, but it only works with objects, arrays and collections, and it cannot be reassigned without losing reactivity.

const n = ref(0); n.value++;
const state = reactive({ count: 0 }); state.count++;

Pitfalls: destructuring a reactive object loses reactivity because you extract a raw value, so use toRefs or storeToRefs with Pinia. Replacing the whole reactive object (state = {...}) breaks the proxy, whereas n.value = {...} is fine.

ref is generally the recommended default because it is composable, works for primitives, and can be passed around without losing the link. reactive is convenient for grouped state. readonly and shallowRef are useful variants when you want to prevent mutation or skip deep conversion.

13 How do Vue components communicate with each other? Medium

The primary patterns are props down and events up. A parent passes data via props declared with defineProps, and listens to child events emitted with defineEmits. For deep trees, provide and inject lets an ancestor share a value with any descendant without prop drilling, and the provider can also expose a function so descendants can call back.

Global shared state is typically handled by Pinia or a small reactive module. Two-way binding on a custom component works by accepting a prop and emitting update:propName, which v-model desugars to.

Slots, including default, named and scoped slots, let a parent inject template content and receive child data. For siblings, lift state to the nearest common parent or use a store.

Avoid $parent, $children and global event-bus patterns. They are considered legacy because they create hidden coupling that is hard to trace, whereas props, events, inject and stores make the data flow explicit and testable.

14 Why is the key attribute important in v-for? Medium

The key gives each rendered item a stable identity so Vue can match old and new nodes during patching. Without a key, Vue uses an in-place patch strategy and reuses DOM nodes by index, which can cause wrong component state, broken input focus or incorrect animations when the list is reordered, filtered or has an item inserted in the middle.

With a unique key, Vue can move, add and remove the correct nodes. Use a stable unique value such as a database id, never the array index, because the index changes when the list changes and defeats the purpose.

<li v-for="item in items" :key="item.id">{{ item.name }}</li>

Keys must be unique among siblings and are not exposed as a prop. For simple static lists that never reorder, an index key is acceptable but still a smell. In TransitionGroup, keys are required for correct move animations.

15 How does v-model work on a custom component? Medium

v-model on a component is syntactic sugar. In Vue 3, v-model="foo" compiles to passing a modelValue prop and listening for update:modelValue. Inside the child you declare and emit it:

<script setup>
const props = defineProps(['modelValue']);
const emit = defineEmits(['update:modelValue']);
</script>
<input :value="props.modelValue" @input="emit('update:modelValue', $event.target.value)" />

Named models use an argument: v-model:title maps to the title prop and update:title event, so a component can support several two-way bindings. Vue 2 used value and input with an optional model option; Vue 3 removed that in favour of the name.

Modifiers such as v-model.trim are not applied automatically on components. The child receives them through the modelModifiers prop and must implement the behaviour. This pattern is how form libraries wrap native inputs with consistent validation and formatting.

16 What are the major features of Vue.js? Medium

Below are the some of major features available with VueJS

  1. Virtual DOM: It uses virtual DOM similar to other existing frameworks such as ReactJS, Ember etc. Virtual DOM

is a light-weight in-memory tree representation of the original HTML DOM and updated without affecting the
original DOM.

  1. Components: Used to create reusable custom elements in VueJS applications.
  2. Templates: VueJS provides HTML based templates that bind the DOM with the Vue instance data
  3. Routing: Navigation between pages is achieved through vue-router
  4. Light weight: VueJS is light weight library compared to other frameworks.

****

17 What are the lifecycle methods of Vue.js? Medium

Lifecycle hooks are a window into how the library you're using works behind-the-scenes. By using these hooks, you
will know when your component is created, added to the DOM, updated, or destroyed. Let's look at lifecycle diagram
before going to each lifecycle hook in detail,

<img src="https://github.com/sudheerj/vuejs-interview-questions/blob/master/images/lifecycle.png" width="400" height="800">

  1. Creation(Initialization):

Creation Hooks allow you to perform actions before your component has even been added to the DOM. You need to use
these hooks if you need to set things up in your component both during client rendering and server rendering.
Unlike other hooks, creation hooks are also run during server-side rendering.

  1. beforeCreate:

This hook runs at the very initialization of your component. hook observes data and initialization events in
your component. Here, data is still not reactive and events that occur during the component's lifecycle have
not been set up yet.

        new Vue({
          data: {
           count: 10
          },
          beforeCreate: function () {
            console.log('Nothing gets called at this moment')
            // `this` points to the view model instance
            console.log('count is ' + this.count);
          }
        })
           // count is undefined
     
  1. created:

This hook is invoked when Vue has set up events and data observation. Here, events are active and access to
reactive data is enabled though templates have not yet been mounted or rendered.

      new Vue({
        data: {
         count: 10
        },
        created: function () {
          // `this` points to the view model instance
          console.log('count is: ' + this.count)
        }
      })
         // count is: 10
    

Note: Remember that, You will not have access to the DOM or the target mounting element (this.$el) inside of
creation hooks

  1. Mounting(DOM Insertion):

Mounting hooks are often the most-used hooks and they allow you to access your component immediately before and
after the first render.

  1. beforeMount:

The beforeMount allows you to access your component immediately before and after the first render.

      new Vue({
        beforeMount: function () {
          // `this` points to the view model instance
          console.log(`this.$el is yet to be created`);
        }
      })
    
  1. mounted:

This is a most used hook and you will have full access to the reactive component, templates, and rendered
DOM (via. this.$el). The most frequently used patterns are fetching data for your component.

    <div id="app">
        <p>I'm text inside the component.</p>
    </div>
      new Vue({
        el: '#app',
        mounted: function() {
          console.log(this.$el.textContent); // I'm text inside the component.
        }
      })
    
  1. Updating (Diff & Re-render):

Updating hooks are called whenever a reactive property used by your component changes, or something else causes
it to re-render

  1. beforeUpdate:

The beforeUpdate hook runs after data changes on your component and the update cycle begins, right before the
DOM is patched and re-rendered.

    <div id="app">
      <p>{{counter}}</p>
    </div>
    ...// rest of the code
      new Vue({
        el: '#app',
        data() {
          return {
            counter: 0
          }
        },
         created: function() {
          setInterval(() => {
            this.counter++
          }, 1000)
        },

        beforeUpdate: function() {
          console.log(this.counter) // Logs the counter value every second, before the DOM updates.
        }
      })
    
  1. updated:

This hook runs after data changes on your component and the DOM re-renders.

    <div id="app">
      <p ref="dom">{{counter}}</p>
    </div>
    ...//
      new Vue({
        el: '#app',
        data() {
          return {
            counter: 0
          }
        },
         created: function() {
          setInterval(() => {
            this.counter++
          }, 1000)
        },
        updated: function() {
          console.log(+this.$refs['dom'].textContent === this.counter) // Logs true every second
        }
      })
    
  1. Destruction (Teardown):

Destruction hooks allow you to perform actions when your component is destroyed, such as cleanup or analytics
sending.

  1. beforeDestroy:

beforeDestroy is fired right before teardown. If you need to cleanup events or reactive subscriptions,
beforeDestroy would probably be the time to do it. Your component will still be fully present and functional.

    new Vue ({
      data() {
        return {
          message: 'Welcome VueJS developers'
        }
      },

      beforeDestroy: function() {
        this.message = null
        delete this.message
      }
    })
    
  1. destroyed:

This hooks is called after your component has been destroyed, its directives have been unbound and its event
listeners have been removed.

    new Vue ({
        destroyed: function() {
          console.log(this) // Nothing to show here
        }
      })
    

****

18 What are the different API styles available? Medium

The Vue components can be created in two different API styles

  1. Options API: The Options API uses component logic using an object of options such as data, props,

computed, methods and life cycle methods etc. The properties will be accessible inside functions using
component instance(i.e, this).

  1. Composition API: The Composition API uses component logic using imported API functions. The Single File

Components(SFCs) requires setup attribute(<script setup>) to use imported variables and functions directly
inside template section.

19 What are the conditional directives? Medium

VueJS provides set of directives to show or hide elements based on conditions. The available directives are: **v-if,
v-else, v-else-if and v-show**

1. v-if: The v-if directive adds or removes DOM elements based on the given expression. For example, the below
button will not show if isLoggedIn is set to false.

<button v-if="isLoggedIn">Logout</button>

You can also control multiple elements with a single v-if statement by wrapping all the elements in a <template>
element with the condition. For example, you can have both label and button together conditionally applied,

<template v-if="isLoggedIn">
  <label> Logout </button>
  <button> Logout </button>
</template>

2. v-else: This directive is used to display content only when the expression adjacent v-if resolves to false.
This is similar to else block in any programming language to display alternative content and it is preceded by v-if
or v-else-if block. You don't need to pass any value to this.
For example, v-else is used to display LogIn button if isLoggedIn is set to false(not logged in).

<button v-if="isLoggedIn"> Logout </button>
<button v-else> Log In </button>

3. v-else-if: This directive is used when we need more than two options to be checked.
For example, we want to display some text instead of LogIn button when ifLoginDisabled property is set to true. This
can be achieved through v-else statement.

<button v-if="isLoggedIn"> Logout </button>
<label v-else-if="isLoginDisabled"> User login disabled </label>
<button v-else> Log In </button>

4. v-show: This directive is similar to v-if but it renders all elements to the DOM and then uses the CSS
display property to show/hide elements. This directive is recommended if the elements are switched on and off
frequently.

<span v-show="user.name">Welcome user,{{user.name}}</span>

****

20 What is the difference between v-show and v-if directives? Medium

Below are some of the main differences between v-show and v-if directives,

  1. v-if only renders the element to the DOM if the expression passes whereas v-show renders all elements to the DOM

and then uses the CSS display property to show/hide elements based on expression.

  1. v-if supports v-else and v-else-if directives whereas v-show doesn't support else directives.
  2. v-if has higher toggle costs while v-show has higher initial render costs. i.e, v-show has a performance

advantage if the elements are switched on and off frequently, while the v-if has the advantage when it comes to
initial render time.

  1. v-if supports <template> tab but v-show doesn't support.

****

Showing 20 of 251 questions

Frequently Asked Questions About Vue.js Interviews

What do hiring managers evaluate in Vue.js technical rounds?

Technical interviewers look for foundational fluency, idiomatic syntax, clarity when communicating complex logic, and awareness of performance trade-offs (e.g. memory footprint, render performance, and network latency) in production environments.

What are the best interview tips for practicing Vue.js questions?

Use active recall: summarize each answer in your own words before revealing the model solution. Focus on explaining why a certain approach is chosen rather than just memorizing code syntax.