issue 117apr 27mmxxvi
est. 2017
Sun, 27 Apr 2026
vol. IX · no. 117
PapersAdda
placement intelligence, since 2017
640+ briefs · 24 campuses · by reservation
verified offers · sourced from r/developersIndia
razorpay₹65.00 LPA· iit-d · sde-1google₹54.00 LPA· iiit-h · swe-imicrosoft₹49.50 LPA· iit-b · sdeatlassian₹38.00 LPA· nit-w · sde-1amazon₹44.20 LPA· bits-p · sde-1uber₹42.00 LPA· iit-kgp · sde-1razorpay₹65.00 LPA· iit-d · sde-1google₹54.00 LPA· iiit-h · swe-imicrosoft₹49.50 LPA· iit-b · sdeatlassian₹38.00 LPA· nit-w · sde-1amazon₹44.20 LPA· bits-p · sde-1uber₹42.00 LPA· iit-kgp · sde-1
section: Interview Questions / interview questions
08 Jun 2026
placement brief / Interview Questions / interview questions / 08 Jun 2026

Vue.js Interview Questions and Answers 2026

Vue.js is a progressive JavaScript framework for building user interfaces. Candidates report that reactivity internals, Composition API patterns, Vue Router...

Aditya Sharma
Aditya's Edit

PapersAdda 2026 Placement Cycle

By Aditya Sharma·Founder & Editor, PapersAdda

What changed in 2026 drives

Mass-recruiter offer letters are flatter for 2026 batch - the 4-5 LPA ASE band has barely budged in three years while inflation eats real wages. Premium tracks (Digital, Pro, Elite, Specialist) are still where the differential lives, and they are entirely test-driven. If you are aiming higher than the default offer, the coding round is not optional pageantry - it is the entire interview.

What I'd actually study for this

  • 01Two solid coding-round answers (1 medium-hard DSA each, with edge-case discussion) > five half-baked ones
  • 02One real project you can defend end-to-end - file paths, design decisions, and what you would change
  • 03One DBMS schema you actually built (not a textbook ER diagram), with at least 3 join-heavy queries written from memory
  • 04Three behavioural STAR stories: failure recovered, conflict handled, ownership taken

Where most candidates trip up

The single biggest mistake is treating company-specific guides as primary prep and DSA as secondary. It is the opposite. Mass recruiters use the test as a filter, but premium tracks at every IT services company use coding to allocate offer band. Spend 70% of prep time on DSA + system fundamentals, 20% on company-specific patterns, 10% on HR rehearsal. Reverse that ratio and you collect the default offer.

Editorial commentary by Aditya Sharma · written for PapersAdda · not generated, not aggregated.

Vue.js is a progressive JavaScript framework for building user interfaces. Candidates report that reactivity internals, Composition API patterns, Vue Router navigation guards, and Pinia state management are the most frequently tested topics in frontend engineering and full-stack developer interviews. This guide covers 50 questions ranging from Vue 3 fundamentals to advanced patterns. Always confirm role-specific framework requirements on the official careers portal of the company you are targeting.

Table of Contents

  1. Vue 3 Fundamentals
  2. Reactivity System
  3. Composition API
  4. Components and Props
  5. Vue Router
  6. Pinia State Management
  7. Performance and Advanced Patterns
  8. 5-Question Mock Test
  9. Frequently Asked Questions

Vue 3 Fundamentals

Q1. What is Vue 3 and what are its key improvements over Vue 2? Easy

Vue 3 is a complete rewrite of the framework released in 2020. Key improvements include the Composition API for better logic reuse, a Proxy-based reactivity system replacing Object.defineProperty, multiple root elements per template (Fragments), Teleport for rendering outside the component tree, Suspense for async component handling, improved TypeScript support, and a smaller bundle size through tree-shaking. The virtual DOM was rewritten for better performance with static hoisting and patch flags.

Q2. What is the Vue instance lifecycle? Easy

Vue 3 lifecycle hooks in order:

HookComposition APIDescription
Before create(setup itself)Instance initializing
Created(after setup)Reactive data ready, no DOM
beforeMountonBeforeMountTemplate compiled, not yet in DOM
mountedonMountedComponent in DOM
beforeUpdateonBeforeUpdateData changed, before re-render
updatedonUpdatedDOM updated
beforeUnmountonBeforeUnmountTeardown starts
unmountedonUnmountedComponent removed
import { onMounted, onBeforeUnmount } from 'vue'

export default {
  setup() {
    onMounted(() => {
      console.log('Component mounted')
    })
    onBeforeUnmount(() => {
      console.log('Cleanup here')
    })
  }
}

Q3. What is the difference between v-show and v-if? Easy

v-if conditionally renders the element. When false, the element and its children are not in the DOM at all. It has higher toggle cost but lower initial cost when condition starts false.

v-show always renders the element but toggles CSS display: none. It has lower toggle cost but always pays the initial render cost.

Use v-if for conditions that rarely change; use v-show for frequently toggled content.

Q4. Explain Vue's template compilation. Medium

Vue templates are compiled to render functions (JavaScript) at build time (or runtime in browser builds). The compiler analyzes the template and generates optimized VNode factory functions. In Vue 3, the compiler adds patch flags to VNodes indicating what can change (props, text, class, style) so the runtime can skip diffing static parts. Static nodes are hoisted outside the render function to avoid re-creation.

// Template: <div class="static">{{ message }}</div>
// Compiles to approximately:
import { createElementVNode, toDisplayString, openBlock, createElementBlock } from 'vue'

const _hoisted_1 = { class: 'static' }
function render(_ctx) {
  return (openBlock(), createElementBlock('div', _hoisted_1,
    toDisplayString(_ctx.message), 1 /* TEXT patch flag */
  ))
}

Q5. What are Vue directives and how do you create a custom directive? Medium

Directives are special attributes prefixed with v- that apply reactive behavior to the DOM. Built-in: v-if, v-for, v-bind, v-on, v-model, v-show, v-slot.

Custom directive with lifecycle hooks:

// Global registration
app.directive('focus', {
  mounted(el, binding) {
    el.focus()
    if (binding.value) {
      el.style.outline = binding.value
    }
  },
  updated(el, binding) {
    if (binding.value !== binding.oldValue) {
      el.style.outline = binding.value
    }
  }
})

// Usage: <input v-focus="'2px solid blue'" />

Reactivity System

Q6. How does Vue 3's reactivity system work? Medium

Vue 3 uses JavaScript Proxy to intercept get/set operations on reactive objects. When a reactive property is accessed during component rendering, Vue tracks the dependency. When the property is mutated, Vue triggers re-renders for all components that depend on it.

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key)  // record dependency
      return target[key]
    },
    set(target, key, value) {
      target[key] = value
      trigger(target, key)  // notify dependents
      return true
    }
  })
}

Vue 2 used Object.defineProperty which could not detect new property additions or array index mutations, requiring Vue.set().

Q7. What is the difference between ref and reactive? Easy

Featurerefreactive
AcceptsAny type (primitive or object)Objects/arrays only
Access.value in JS, auto-unwrapped in templateDirect property access
DestructuringSafe (still reactive)Loses reactivity
Replace entirelySupported (reassign .value)Not supported
TypeScriptRef<T> typePlain object type
import { ref, reactive } from 'vue'

const count = ref(0)
count.value++ // JS
// {{ count }} in template (auto-unwrapped)

const state = reactive({ count: 0, name: 'Vue' })
state.count++ // direct access
const { count } = state // BUG: count is no longer reactive
const { count: countRef } = toRefs(state) // CORRECT

Q8. What is computed and how does it differ from a method? Easy

computed is cached based on its reactive dependencies. It only re-evaluates when a dependency changes. A method re-runs every time the component re-renders.

import { ref, computed } from 'vue'

const items = ref([1, 2, 3, 4, 5])

// Cached: only recomputes when items changes
const total = computed(() => items.value.reduce((a, b) => a + b, 0))

// Runs on every render even if items hasn't changed
function getTotal() {
  return items.value.reduce((a, b) => a + b, 0)
}

Use computed for derived state; use methods for event handlers or operations with side effects.

Q9. Predict the output: Medium

import { ref, watch } from 'vue'

const count = ref(0)

watch(count, (newVal, oldVal) => {
  console.log(`${oldVal} -> ${newVal}`)
})

count.value = 1
count.value = 2

Output:

0 -> 1
1 -> 2

Explanation: watch by default is lazy (does not run on initial value) and runs after each synchronous mutation. Each assignment triggers the watcher with the previous and new values. The watcher is not batched here because each mutation is a separate operation that triggers Vue's scheduler.

Q10. What is watchEffect and when do you use it over watch? Medium

watchEffect automatically tracks dependencies accessed during its execution and re-runs when any of them change. It runs immediately on setup (eager by default).

import { ref, watchEffect, watch } from 'vue'

const userId = ref(1)

// watchEffect: tracks userId automatically, runs immediately
watchEffect(async () => {
  const data = await fetchUser(userId.value) // userId tracked
  user.value = data
})

// watch: explicit source, lazy by default, gives old/new values
watch(userId, async (newId, oldId) => {
  const data = await fetchUser(newId)
  user.value = data
}, { immediate: true })

Use watchEffect for side effects that depend on multiple reactive sources and don't need old values. Use watch when you need explicit control, old values, or lazy execution.


Composition API

Q11. What is the setup() function? Easy

setup() is the entry point for the Composition API. It runs before component creation, before beforeCreate. It receives props and context (attrs, slots, emit, expose). Everything returned from setup() is available in the template. With the <script setup> syntax sugar, top-level declarations are automatically exposed.

// Options API with setup()
export default {
  props: ['title'],
  setup(props, { emit, expose }) {
    const count = ref(0)
    function increment() { count.value++ }
    expose({ count }) // expose to parent via template ref
    return { count, increment }
  }
}

// Script setup (preferred)
<script setup>
const props = defineProps(['title'])
const emit = defineEmits(['update'])
const count = ref(0)
</script>

Q12. What are composables and how do you create one? Medium

Composables are functions that use the Composition API to encapsulate and reuse stateful logic. They follow the use naming convention.

// composables/useCounter.js
import { ref, computed } from 'vue'

export function useCounter(initial = 0) {
  const count = ref(initial)
  const double = computed(() => count.value * 2)

  function increment() { count.value++ }
  function decrement() { count.value-- }
  function reset() { count.value = initial }

  return { count, double, increment, decrement, reset }
}

// composables/useFetch.js
import { ref, watchEffect } from 'vue'

export function useFetch(url) {
  const data = ref(null)
  const error = ref(null)
  const loading = ref(true)

  watchEffect(async () => {
    loading.value = true
    error.value = null
    try {
      const res = await fetch(url.value ?? url)
      data.value = await res.json()
    } catch (e) {
      error.value = e
    } finally {
      loading.value = false
    }
  })

  return { data, error, loading }
}

// Usage in component
<script setup>
import { useCounter } from '@/composables/useCounter'
const { count, increment } = useCounter(10)
</script>

Q13. How does provide/inject work in Vue 3? Medium

provide makes a value available to all descendant components without passing it through props. inject retrieves it in a descendant.

// Parent (or App.vue)
import { provide, ref } from 'vue'

const theme = ref('dark')
provide('theme', theme) // provide reactive ref

// Deep child
import { inject } from 'vue'

const theme = inject('theme') // same reactive ref
const theme = inject('theme', 'light') // with default

// Typed injection (recommended)
import { InjectionKey } from 'vue'
const ThemeKey: InjectionKey<Ref<string>> = Symbol('theme')
provide(ThemeKey, theme)
const theme = inject(ThemeKey) // type-safe

Prefer Symbol keys to avoid naming conflicts. For app-wide state, Pinia is more appropriate than provide/inject.

Q14. What are Vue 3 Teleport and Suspense? Medium

Teleport renders a component's template in a different DOM location while keeping it logically inside the component tree.


<Teleport to="body">
  <div class="modal" v-if="showModal">
    <slot />
    <button @click="showModal = false">Close</button>
  </div>
</Teleport>

Suspense handles async setup functions and async components, showing fallback content while loading.

<Suspense>
  <template #default>
    <AsyncComponent />
  </template>
  <template #fallback>
    <LoadingSpinner />
  </template>
</Suspense>

AsyncComponent can have async setup() that fetches data; Suspense waits for it to resolve.


Components and Props

Q15. What is the difference between props and emits in Vue 3? Easy

Props are read-only data passed from parent to child. Emits are events the child fires to communicate with the parent. This enforces one-way data flow.

<script setup>
// Child component
const props = defineProps({
  modelValue: String,  // v-model binding
  label: {
    type: String,
    required: true
  },
  count: {
    type: Number,
    default: 0,
    validator: (v) => v >= 0
  }
})

const emit = defineEmits(['update:modelValue', 'submit'])

function handleInput(e) {
  emit('update:modelValue', e.target.value)
}
</script>

Q16. How does v-model work in Vue 3? Medium

v-model on a component is syntactic sugar for binding a prop and listening to an update event.


<CustomInput v-model="text" />

<CustomInput :modelValue="text" @update:modelValue="text = $event" />


<UserForm v-model:first="firstName" v-model:last="lastName" />
// CustomInput.vue
<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>
<template>
  <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template>

In Vue 2, v-model used value prop and input event. In Vue 3 it uses modelValue and update:modelValue.

Q17. What are slots in Vue and what is the difference between named and scoped slots? Medium

Slots allow parent components to inject template content into a child component.



<template>
  <header><slot name="header" /></header>
  <main><slot /></main>  
  <footer><slot name="footer" /></footer>
</template>


<BaseLayout>
  <template #header><h1>Title</h1></template>
  <p>Main content</p>
  <template #footer>Footer text</template>
</BaseLayout>

Scoped slots pass data from child back to parent slot content:


<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      <slot :item="item" :index="index" />
    </li>
  </ul>
</template>


<DataList :items="users">
  <template #default="{ item, index }">
    <span>{{ index }}: {{ item.name }}</span>
  </template>
</DataList>

Q18. What is the defineExpose macro in script setup? Medium

By default, <script setup> components are closed: nothing is accessible to parent via template ref. defineExpose explicitly exposes selected properties.

// Child.vue
<script setup>
import { ref } from 'vue'
const count = ref(0)
const internalState = ref('private')

defineExpose({ count }) // only count is accessible
</script>

// Parent.vue
<script setup>
import { ref, onMounted } from 'vue'
const childRef = ref(null)

onMounted(() => {
  console.log(childRef.value.count) // works
  console.log(childRef.value.internalState) // undefined
})
</script>
<template>
  <Child ref="childRef" />
</template>

Vue Router

Q19. What are the types of navigation guards in Vue Router 4? Medium

GuardLocationUse case
beforeEachGlobalAuth check, logging
afterEachGlobalAnalytics, loading stop
beforeResolveGlobalFetch data before render
beforeEnterPer-routeRoute-specific auth
onBeforeRouteLeaveIn-componentUnsaved changes warning
onBeforeRouteUpdateIn-componentSame component, param change
// Global guard
router.beforeEach(async (to, from) => {
  if (to.meta.requiresAuth && !isAuthenticated()) {
    return { name: 'Login', query: { redirect: to.fullPath } }
  }
})

// In-component (Composition API)
import { onBeforeRouteLeave } from 'vue-router'

onBeforeRouteLeave((to, from) => {
  if (hasUnsavedChanges.value) {
    return confirm('Leave without saving?')
  }
})

<router-link> is a component that renders an <a> tag and integrates with Vue Router. It adds active classes, handles accessibility, and prevents default navigation. It is declarative.

router.push() is programmatic navigation from JavaScript code.

// router-link: declarative
<router-link :to="{ name: 'User', params: { id: userId } }">Profile</router-link>

// programmatic
import { useRouter } from 'vue-router'
const router = useRouter()

async function login() {
  await performLogin()
  router.push({ name: 'Dashboard' })
}

// replace (no history entry)
router.replace('/home')

// relative navigation
router.push({ path: '../parent' })

Q21. How do you implement dynamic routes and route params? Medium

// router/index.js
const routes = [
  {
    path: '/users/:id',
    name: 'User',
    component: UserView,
    meta: { requiresAuth: true }
  },
  {
    path: '/posts/:category/:slug',
    component: PostView
  },
  // Catch-all (404)
  {
    path: '/:pathMatch(.*)*',
    name: 'NotFound',
    component: NotFoundView
  }
]

// In component
import { useRoute } from 'vue-router'
const route = useRoute()

console.log(route.params.id)     // dynamic segment
console.log(route.query.page)    // query string ?page=2
console.log(route.meta.requiresAuth)

// Watch param changes (same component re-used)
watch(() => route.params.id, (newId) => {
  fetchUser(newId)
})

Pinia State Management

Q22. How do you define and use a Pinia store? Easy

// stores/counter.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

// Setup store (Composition API style - preferred)
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const double = computed(() => count.value * 2)

  function increment() { count.value++ }
  function reset() { count.value = 0 }

  return { count, double, increment, reset }
})

// Options store (alternative)
export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  getters: {
    double: (state) => state.count * 2
  },
  actions: {
    increment() { this.count++ }
  }
})

// In component
<script setup>
import { useCounterStore } from '@/stores/counter'
import { storeToRefs } from 'pinia'

const store = useCounterStore()
const { count, double } = storeToRefs(store) // reactive destructuring
</script>

Q23. What is storeToRefs and why is it needed? Medium

When you destructure a Pinia store directly, reactive properties lose reactivity. storeToRefs wraps each reactive property in a ref so destructured values remain reactive in the template.

const store = useCounterStore()

// WRONG: count is not reactive
const { count, double } = store

// CORRECT: count and double are reactive refs
const { count, double } = storeToRefs(store)

// Actions can be destructured directly (not reactive state)
const { increment, reset } = store

Q24. How does Pinia handle persistence and plugins? Advanced

Pinia supports plugins that can intercept store creation. The popular pinia-plugin-persistedstate handles localStorage persistence.

// Custom plugin: log all actions
function myPlugin({ store }) {
  store.$onAction(({ name, args, after, onError }) => {
    console.log(`Action: ${name}`, args)
    after((result) => console.log(`Result:`, result))
    onError((error) => console.error(`Error:`, error))
  })

  // Subscribe to state changes
  store.$subscribe((mutation, state) => {
    localStorage.setItem(store.$id, JSON.stringify(state))
  })
}

// main.js
const pinia = createPinia()
pinia.use(myPlugin)

// With persisted state plugin
import { createPersistedState } from 'pinia-plugin-persistedstate'
pinia.use(createPersistedState({
  storage: localStorage,
  serializer: { serialize: JSON.stringify, deserialize: JSON.parse }
}))

Performance and Advanced Patterns

Q25. What is the KeepAlive component and when do you use it? Medium

<KeepAlive> caches component instances when they are toggled off, preserving their state. Lifecycle hooks onActivated and onDeactivated fire instead of mounted/unmounted.

<KeepAlive :include="['UserList']" :max="10">
  <component :is="currentTab" />
</KeepAlive>
import { onActivated, onDeactivated } from 'vue'

onActivated(() => {
  // refresh data if needed
  if (needsRefresh.value) fetchData()
})
onDeactivated(() => {
  // pause timers, subscriptions
})

Use when switching between tabs/views that are expensive to remount and benefit from preserved scroll position or form state.

Q26. How do you optimize Vue 3 performance? Advanced

  1. v-once: render static content once, never update
  2. v-memo: memoize sub-tree based on a dependency array
  3. shallowRef / shallowReactive: skip deep reactivity for large data structures
  4. defineAsyncComponent: code-split heavy components
  5. Virtual scrolling: for large lists (vue-virtual-scroller)
// v-memo: only update when item.id or selected changes
<div v-for="item in list" :key="item.id" v-memo="[item.id, item.selected]">
  {{ item.name }} - {{ expensiveCompute(item) }}
</div>

// Async component with loading state
import { defineAsyncComponent } from 'vue'

const HeavyChart = defineAsyncComponent({
  loader: () => import('./HeavyChart.vue'),
  loadingComponent: LoadingSpinner,
  errorComponent: ErrorDisplay,
  delay: 200,
  timeout: 3000
})

// shallowRef for large external data
import { shallowRef } from 'vue'
const tableData = shallowRef([]) // Vue tracks only .value change, not nested

Q27. What is the difference between Options API and Composition API? When do you use each? Medium

AspectOptions APIComposition API
OrganizationBy type (data, methods, computed)By feature/concern
ReuseMixins (naming conflicts, unclear source)Composables (explicit, no conflicts)
TypeScriptLimited inferenceFirst-class support
Logic sharingHardEasy via composables
Learning curveLower for beginnersSteeper
Code sizeMore boilerplate for simple casesMore concise for complex cases

Use Options API for small, simple components or when onboarding developers new to Vue. Use Composition API for large components with multiple concerns, when TypeScript is used, or when building reusable logic.

Q28. How does Vue 3 handle SSR (Server-Side Rendering)? Advanced

Vue 3 supports SSR via @vue/server-renderer or higher-level frameworks like Nuxt 3.

// server.js (Node.js)
import { createSSRApp } from 'vue'
import { renderToString } from '@vue/server-renderer'

const app = createSSRApp({
  data: () => ({ count: 1 }),
  template: '<button @click="count++">{{ count }}</button>'
})

const html = await renderToString(app)
// Output: <button>1</button>

Vue uses hydration to attach event listeners on the client to server-rendered HTML. Components can use onServerPrefetch to fetch data during SSR. useSSRContext provides the SSR context. Nuxt 3 handles routing, data fetching with useFetch/useAsyncData, and module-level SSR configuration.

Q29. What is the Vue 3 reactivity transform (experimental) and its successor? Advanced

The reactivity transform was a compile-time syntax sugar that allowed writing $ref instead of ref and accessing values without .value. It was deprecated in Vue 3.3 in favor of a more targeted solution.

Vue 3.3+ introduces typed defineProps/defineEmits macros, generic components, and better TypeScript support. The community-accepted alternative for reducing .value boilerplate is the vue-macros library with $ref transforms for those who prefer it, while official Vue recommendation remains standard Composition API syntax.

Q30. Predict the output: Advanced

import { ref, watchEffect, nextTick } from 'vue'

const count = ref(0)
let effectRuns = 0

watchEffect(() => {
  effectRuns++
  console.log('effect:', count.value)
})

count.value = 1
count.value = 2

await nextTick()

console.log('effectRuns:', effectRuns)

Output:

effect: 0
effect: 2
effectRuns: 2

Explanation: watchEffect runs immediately (effect: 0 is the initial run). The two synchronous assignments to count.value are batched by Vue's scheduler. Only the final value (2) triggers a re-run after the current synchronous code finishes. nextTick waits for the DOM update queue to flush. So effectRuns is 2 (initial + one batched update).

Q31. How do you implement a global error handler in Vue 3? Advanced

// main.js
const app = createApp(App)

app.config.errorHandler = (error, instance, info) => {
  console.error('Vue error:', error)
  console.log('Component:', instance?.$options.name)
  console.log('Info:', info) // e.g., 'setup function'
  sendToErrorTracking(error)
}

app.config.warnHandler = (msg, instance, trace) => {
  // suppress in tests
  if (process.env.NODE_ENV !== 'test') {
    console.warn(msg, trace)
  }
}

// In-component error boundary
const error = ref(null)
onErrorCaptured((err, instance, info) => {
  error.value = err
  return false // prevent propagation to parent handlers
})

Q32. What are render functions and h() in Vue 3? Advanced

The h() function (short for hyperscript) creates VNodes directly without templates. Used for programmatic rendering, higher-order components, and cases where templates are limiting.

import { h, ref } from 'vue'

// Functional component as render function
export default {
  name: 'MyButton',
  props: ['label', 'type'],
  setup(props, { slots, emit }) {
    const loading = ref(false)

    return () => h(
      'button',
      {
        type: props.type || 'button',
        class: ['btn', { 'btn-loading': loading.value }],
        onClick: () => emit('click')
      },
      loading.value ? 'Loading...' : slots.default?.() ?? props.label
    )
  }
}

Additional Topics

Q33. What is Vue's transition system? Medium

The <Transition> component applies CSS or JavaScript animations to entering/leaving elements.

<Transition name="fade" mode="out-in">
  <component :is="activeView" :key="activeView" />
</Transition>

<style>
.fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }
.fade-enter-from, .fade-leave-to { opacity: 0; }
</style>

mode="out-in" waits for the leaving transition before the entering transition starts. <TransitionGroup> handles lists with FLIP animations.

Q34. How does Vue 3 handle TypeScript? Medium

Vue 3 is written in TypeScript and provides first-class TS support.

<script setup lang="ts">
import { ref, computed } from 'vue'

interface User {
  id: number
  name: string
  email: string
}

const user = ref<User | null>(null)
const displayName = computed(() => user.value?.name ?? 'Guest')

const props = defineProps<{
  title: string
  count?: number
}>()

// withDefaults for default values
const propsWithDefaults = withDefaults(defineProps<{
  items: string[]
  size: 'sm' | 'md' | 'lg'
}>(), {
  items: () => [],
  size: 'md'
})

const emit = defineEmits<{
  update: [value: string]
  submit: [payload: User]
}>()
</script>

Q35. What are Vue 3 key best practices for large applications? Advanced

  1. Folder structure: organize by feature (not by type)
  2. Auto-import: use unplugin-auto-import and unplugin-vue-components to avoid repetitive imports
  3. Composables: extract all reusable logic; keep components thin
  4. Pinia stores: one store per domain; use setup stores for complex logic
  5. Lazy loading: defineAsyncComponent + router-level code splitting
  6. Error boundaries: onErrorCaptured at page level
  7. Testing: Vitest + Vue Test Utils for unit; Playwright for E2E
  8. Performance: use Vue DevTools profiler, avoid heavy watchers, prefer computed
// router with lazy loading
const routes = [
  {
    path: '/dashboard',
    component: () => import('@/views/Dashboard.vue') // code split
  }
]

5-Question Mock Test

Q1. What does storeToRefs do and why is direct destructuring of a Pinia store incorrect?

Q2. Explain the difference between watchEffect and watch. In what scenario would you choose watch over watchEffect?

Q3. How does v-model work on a custom component in Vue 3? Write the child component implementation for <CustomInput v-model="text" />.

Q4. What is the output of the following code?

const count = ref(0)
const double = computed(() => count.value * 2)
count.value = 5
console.log(double.value)
count.value = 10
console.log(double.value)

Q5. What is the difference between ref and reactive? When would you use reactive over ref?

Answers:

A1. storeToRefs wraps each state/getter in a reactive ref, preserving reactivity after destructuring. Direct destructuring extracts plain values that are no longer connected to the store's reactive state.

A2. watchEffect auto-tracks dependencies and is eager (runs immediately). watch requires explicit sources and is lazy. Choose watch when you need the old value, need to react to a specific source only, or want lazy evaluation.

A3. Child needs defineProps(['modelValue']), defineEmits(['update:modelValue']), and :value="modelValue" + @input="$emit('update:modelValue', $event.target.value)".

A4. Output: 10 then 20. Computed updates synchronously when accessed after its dependency changes.

A5. ref works for all types and requires .value. reactive creates a deep reactive object without .value but loses reactivity on destructure. Use reactive when managing a closely related group of state properties that form a single logical object (e.g., form state).


Frequently Asked Questions

What is Vue 3 Composition API and why was it introduced?

The Composition API organizes component logic by feature rather than by Vue option type (data/methods/computed). It was introduced to solve the fragmentation problem in large components where related logic was scattered across multiple options, to replace mixins with conflict-free composables, and to provide better TypeScript inference.

What is Pinia and how does it compare to Vuex?

Pinia is the official Vue state management library. It removes mutations (making Vuex's three-step commit-mutation-state flow unnecessary), supports multiple flat stores without module nesting, has better TypeScript support, and uses a simpler API. Vuex 4 is now in maintenance mode.

How do Vue 3 and React compare for large applications?

Vue 3 offers a more opinionated structure with the Options/Composition API duality, official router and state management (Vue Router, Pinia), and Single File Components. React is more minimal by design, relying on the ecosystem for routing (React Router) and state (Redux, Zustand). Vue's reactivity system is more automatic; React requires explicit dependency arrays. Both are suitable for large applications; choice depends on team familiarity and ecosystem requirements.

What is the internal mesh of related topics?

Methodology applied to this articlelast verified 8 Jun 2026
Sources used
Public exam-pattern documents, official recruiter pages, and verified candidate reports on r/developersIndia and LinkedIn.
Verification window
Page last edited 8 Jun 2026 by Aditya Sharma. Numbers and patterns sanity-checked against the most recent 2026 cycle drives we tracked.
What we did NOT do
  • No fabricated salary numbers or success rates. If we quote a range, it's sourced.
  • No noun-substituted templates. This article was not generated by swapping company names in a stock prompt.
  • No paid placements, sponsored coaching links, or affiliate-shilled course pushes.
Verification policy: /editorial-standards/. Found something incorrect? Submit a correction - we respond within 48 hours.

topic cluster

More resources in Interview Questions

Use the category hub to browse similar questions, exam patterns, salary guides, and preparation resources related to this topic.

Open Interview Questions hubBrowse all articles

paid contributor programme

Sat this this year? Share your story, earn ₹500.

First-person experience reports help future candidates prep smarter. We pay verified contributors ₹500 via UPI per accepted story with byline.

Submit your story →

ready to practice?

Take a free timed mock test

Put what you learned into practice. Our mock tests match the 2026 pattern with timer, navigator, reveal, and score breakdown. No signup.

Start free mock test →
related guides
more from PapersAdda
Company Placement PapersAmazon Placement Papers 2026: SDE-1 OA, Loop and Bar Raiser Guide
19 min read
Company Placement PapersMicrosoft Placement Papers 2026: SDE-1 OA, Loop and AA Round Guide
15 min read
Company Placement PapersAccenture Interview Questions 2026 (with Answers for Freshers)
13 min read
Company Placement PapersAirbnb Placement Papers 2026 – Questions, Answers & Complete Interview Guide
11 min read

Share this guide