Tutorials Logic, IN info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Website Development
Practice
Quiz Challenge Interview Questions Certification Practice
Tools
Online Compiler JSON Formatter Regex Tester CSS Unit Converter Color Picker
Compiler Tools
Vue.js

Top 50 Vue.js Interview Questions

Curated questions covering Composition API, reactivity, Pinia, Vue Router, directives, lifecycle hooks, Vuex, and Vue 3 features.

01

What is Vue.js and what are its key features?

Vue.js is a progressive JavaScript framework for building user interfaces. Key features: reactive data binding, component-based architecture, Composition API (Vue 3), Options API, virtual DOM, Vue Router, Pinia state management, single-file components (.vue), and progressive adoption (can be used for a single widget or a full SPA).

02

What is the difference between Vue 2 and Vue 3?

  • Composition API - Vue 3 introduces setup() and composables as an alternative to Options API.
  • Performance - Vue 3 is ~55% smaller, faster rendering, better tree-shaking.
  • Fragments - Vue 3 components can have multiple root elements.
  • Teleport - built-in component to render content outside the component tree.
  • Suspense - built-in async component loading.
  • TypeScript - Vue 3 is written in TypeScript with first-class TS support.
03

What is the difference between the Options API and Composition API?

  • Options API - organizes code by option type (data, methods, computed, watch). Easier for beginners. Logic for one feature is spread across multiple options.
  • Composition API - organizes code by logical concern using setup(). Better code reuse via composables. Better TypeScript support. Preferred for complex components.
Example
// Options API\nexport default {\n  data() { return { count: 0 }; },\n  methods: { increment() { this.count++; } }\n};\n\n// Composition API\nconst count = ref(0);\nconst increment = () => count.value++;
04

What is the Vue 3 setup() function?

setup() is the entry point for the Composition API. It runs before the component is created, before beforeCreate. It receives props and context as arguments. Variables and functions returned from setup() are available in the template.

Example
export default {\n  props: ["userId"],\n  setup(props, { emit, attrs, slots }) {\n    const user = ref(null);\n    onMounted(() => fetchUser(props.userId).then(u => user.value = u));\n    return { user };\n  }\n};
05

What is the difference between ref() and reactive() in Vue 3?

  • ref() - wraps a primitive or object in a reactive reference. Access/mutate via .value in JavaScript; no .value needed in templates.
  • reactive() - makes a plain object deeply reactive. Cannot be used with primitives. Loses reactivity if destructured.
  • Prefer ref() for everything - it is more consistent and works with primitives.
Example
const count = ref(0);\ncount.value++; // in JS\n// {{ count }} in template (no .value)\n\nconst state = reactive({ name: "Alice", age: 30 });\nstate.name = "Bob"; // direct mutation OK
06

What is the difference between computed() and watch() in Vue 3?

  • computed() - derives a value from reactive state. Cached - only re-evaluates when dependencies change. Use for derived data.
  • watch() - runs a side effect when reactive state changes. Use for async operations, DOM manipulation, or calling external APIs.
  • watchEffect() - like watch but automatically tracks dependencies.
Example
const fullName = computed(() => `${firstName.value} ${lastName.value}`);\n\nwatch(userId, async (newId) => {\n  user.value = await fetchUser(newId);\n});
07

What are Vue composables?

Composables are functions that encapsulate and reuse stateful logic using the Composition API. They are the Vue 3 equivalent of React hooks. By convention, composable names start with "use".

Example
// useFetch.js\nexport function useFetch(url) {\n  const data = ref(null);\n  const error = ref(null);\n  const loading = ref(true);\n\n  fetch(url)\n    .then(r => r.json())\n    .then(d => { data.value = d; loading.value = false; })\n    .catch(e => { error.value = e; loading.value = false; });\n\n  return { data, error, loading };\n}\n\n// Usage\nconst { data, loading } = useFetch("/api/users");
08

What is the Vue 3 script setup syntax?

<script setup> is syntactic sugar for the Composition API. Variables, functions, and imports declared inside are automatically available in the template. No need to return anything. It is the recommended way to write Vue 3 components.

Example
<script setup>\nimport { ref, computed } from "vue";\nimport UserCard from "./UserCard.vue";\n\nconst props = defineProps({ userId: Number });\nconst emit = defineEmits(["update"]);\n\nconst count = ref(0);\nconst doubled = computed(() => count.value * 2);\n</script>
09

What is the difference between defineProps and defineEmits?

  • defineProps() - declares the props a component accepts. In script setup, it replaces the props option. Returns the props object.
  • defineEmits() - declares the events a component can emit. Returns the emit function. Provides type checking for emitted events.
Example
<script setup>\nconst props = defineProps({\n  title: { type: String, required: true },\n  count: { type: Number, default: 0 }\n});\n\nconst emit = defineEmits(["update:count", "close"]);\nemit("update:count", props.count + 1);\n</script>
10

What is v-model and how does it work in Vue 3?

v-model creates two-way data binding. In Vue 3, v-model on a component is shorthand for :modelValue + @update:modelValue. Multiple v-model bindings are supported on a single component.

Example
<!-- Parent -->\n<UserInput v-model="username" />\n<!-- Equivalent to: -->\n<UserInput :modelValue="username" @update:modelValue="username = $event" />\n\n<!-- Child component -->\nconst props = defineProps(["modelValue"]);\nconst emit = defineEmits(["update:modelValue"]);\nemit("update:modelValue", newValue);
11

What is the difference between v-show and v-if?

  • v-if - conditionally renders the element. Removes/adds it from the DOM. Higher toggle cost, lower initial render cost if condition is false.
  • v-show - always renders the element but toggles display:none. Lower toggle cost, higher initial render cost.
  • Use v-if for conditions that rarely change; v-show for frequent toggling.
12

What is the difference between v-for with and without a key?

Without key, Vue reuses DOM elements in place when the list changes, which can cause bugs with stateful elements (inputs, animations). With a unique key, Vue can track each element and correctly add/remove/reorder them.

Example
<!-- Bad: index as key causes issues on reorder -->\n<li v-for="(item, i) in items" :key="i">{{ item.name }}</li>\n\n<!-- Good: stable unique ID -->\n<li v-for="item in items" :key="item.id">{{ item.name }}</li>
13

What are Vue lifecycle hooks in Vue 3?

  • onBeforeMount / onMounted - before/after component is mounted to DOM.
  • onBeforeUpdate / onUpdated - before/after reactive data change causes re-render.
  • onBeforeUnmount / onUnmounted - before/after component is removed from DOM.
  • onErrorCaptured - catches errors from child components.
  • setup() runs before all hooks (replaces beforeCreate/created).
Example
import { onMounted, onUnmounted } from "vue";\n\nonMounted(() => {\n  window.addEventListener("resize", handler);\n});\nonUnmounted(() => {\n  window.removeEventListener("resize", handler);\n});
14

What is Pinia and how does it differ from Vuex?

Pinia is the official Vue state management library (replaces Vuex). Differences: no mutations (only state + actions), better TypeScript support, simpler API, modular by default, devtools support, and works with both Options and Composition API.

Example
// stores/user.js\nexport const useUserStore = defineStore("user", () => {\n  const user = ref(null);\n  const isLoggedIn = computed(() => !!user.value);\n\n  async function login(credentials) {\n    user.value = await api.login(credentials);\n  }\n\n  return { user, isLoggedIn, login };\n});
15

What is the difference between Pinia and Vuex?

  • Vuex - requires mutations for synchronous state changes, actions for async. Verbose boilerplate. Vuex 4 supports Vue 3 but is in maintenance mode.
  • Pinia - no mutations; actions handle both sync and async. Simpler, smaller, better TypeScript. Official recommendation for Vue 3.
16

What is Vue Router and how do you configure routes?

Vue Router is the official routing library for Vue.js. Configure routes with createRouter() and createWebHistory().

Example
const router = createRouter({\n  history: createWebHistory(),\n  routes: [\n    { path: "/", component: Home },\n    { path: "/users/:id", component: User },\n    { path: "/admin", component: Admin, meta: { requiresAuth: true } },\n    { path: "/:pathMatch(.*)*", component: NotFound }\n  ]\n});
17

What is the difference between createWebHistory and createWebHashHistory?

  • createWebHistory() - uses HTML5 History API (clean URLs: /users/1). Requires server configuration to redirect all routes to index.html.
  • createWebHashHistory() - uses URL hash (#/users/1). No server configuration needed. Works with static file hosting.
18

What are Vue Router navigation guards?

Navigation guards control route access. Types: global (beforeEach, afterEach), per-route (beforeEnter), and in-component (onBeforeRouteLeave, onBeforeRouteUpdate).

Example
router.beforeEach((to, from) => {\n  const auth = useAuthStore();\n  if (to.meta.requiresAuth && !auth.isLoggedIn) {\n    return { path: "/login", query: { redirect: to.fullPath } };\n  }\n});
19

What is the difference between useRoute and useRouter?

  • useRoute() - returns the current route object (params, query, meta, path, name). Reactive.
  • useRouter() - returns the router instance for programmatic navigation (push, replace, go, back).
Example
const route = useRoute();\nconst router = useRouter();\n\nconst userId = route.params.id;\nrouter.push({ name: "user", params: { id: 1 } });
20

What is the Vue Teleport component?

Teleport renders a component's template in a different part of the DOM (outside the component tree) while keeping it logically inside the component. Used for modals, tooltips, and notifications that need to escape overflow/z-index constraints.

Example
<template>\n  <button @click="open = true">Open Modal</button>\n  <Teleport to="body">\n    <div v-if="open" class="modal">\n      <p>Modal content</p>\n      <button @click="open = false">Close</button>\n    </div>\n  </Teleport>\n</template>
21

What is the Vue Suspense component?

Suspense handles async components and async setup() functions. It shows a fallback slot while waiting for async operations to complete. Works with async components (defineAsyncComponent) and components with async setup().

Example
<Suspense>\n  <template #default>\n    <AsyncUserProfile /> <!-- has async setup() -->\n  </template>\n  <template #fallback>\n    <LoadingSpinner />\n  </template>\n</Suspense>
22

What is defineAsyncComponent in Vue 3?

defineAsyncComponent lazily loads a component only when it is needed. Supports loading/error states and timeout configuration.

Example
const UserProfile = defineAsyncComponent({\n  loader: () => import("./UserProfile.vue"),\n  loadingComponent: Spinner,\n  errorComponent: ErrorDisplay,\n  delay: 200,\n  timeout: 3000\n});
23

What is the difference between provide and inject in Vue 3?

provide/inject enables dependency injection across the component tree without prop drilling. A parent provides a value; any descendant can inject it. Use with readonly() to prevent mutation from children.

Example
// Parent\nconst theme = ref("dark");\nprovide("theme", readonly(theme));\n\n// Any descendant\nconst theme = inject("theme");\n// inject("theme", "light") // with default value
24

What is the difference between shallow ref and deep reactivity in Vue 3?

  • ref() / reactive() - deeply reactive. Nested objects are also reactive.
  • shallowRef() - only the .value assignment is reactive. Nested properties are not tracked.
  • shallowReactive() - only top-level properties are reactive.
  • Use shallow variants for large objects where deep reactivity is unnecessary for performance.
25

What is watchEffect() and how does it differ from watch()?

  • watchEffect() - automatically tracks reactive dependencies used inside it. Runs immediately on creation. No need to specify dependencies.
  • watch() - explicitly specifies what to watch. Lazy by default (does not run on creation). Provides old and new values.
Example
// watchEffect - auto-tracks, runs immediately\nwatchEffect(() => {\n  console.log(count.value, name.value); // tracks both\n});\n\n// watch - explicit, lazy\nwatch(count, (newVal, oldVal) => {\n  console.log(newVal, oldVal);\n});
26

What are Vue custom directives?

Custom directives add low-level DOM manipulation behavior to elements. Define with app.directive() globally or locally in a component. Hooks: created, beforeMount, mounted, beforeUpdate, updated, beforeUnmount, unmounted.

Example
app.directive("focus", {\n  mounted(el) { el.focus(); }\n});\n\n// Usage\n<input v-focus />
27

What is the difference between v-bind and v-on shorthand?

  • v-bind:attr="value" shorthand: :attr="value" - dynamically binds an attribute or prop.
  • v-on:event="handler" shorthand: @event="handler" - attaches an event listener.
  • v-bind without argument: v-bind="obj" - binds all properties of an object as attributes.
Example
<input :value="name" @input="name = $event.target.value">\n<component v-bind="{ id: 1, class: 'active' }">
28

What is the Vue 3 defineExpose() macro?

In script setup, component internals are private by default. defineExpose() explicitly exposes properties/methods to parent components accessing the component via template ref.

Example
<script setup>\nconst count = ref(0);\nfunction reset() { count.value = 0; }\n\ndefineExpose({ count, reset }); // parent can access these\n</script>\n\n// Parent\nconst childRef = ref();\nchildRef.value.reset();
29

What is the difference between toRef() and toRefs()?

  • toRef(obj, key) - creates a reactive ref linked to a single property of a reactive object. Maintains reactivity when passed around.
  • toRefs(obj) - converts all properties of a reactive object to refs. Used to destructure reactive objects without losing reactivity.
Example
const state = reactive({ name: "Alice", age: 30 });\n\n// toRefs - safe destructuring\nconst { name, age } = toRefs(state);\nname.value = "Bob"; // still reactive
30

What is the Vue 3 app.use() and plugin system?

Plugins extend Vue functionality globally. A plugin is an object with an install() method or a function. Use app.use(plugin, options) to install. Common plugins: Vue Router, Pinia, i18n, custom UI libraries.

Example
// Plugin definition\nconst myPlugin = {\n  install(app, options) {\n    app.config.globalProperties.$translate = (key) => options[key];\n    app.component("MyComponent", MyComponent);\n    app.directive("focus", focusDirective);\n  }\n};\n\napp.use(myPlugin, { hello: "Bonjour" });
31

What is the difference between v-model modifiers .lazy, .number, and .trim?

  • .lazy - syncs input with data on change event instead of input event (less frequent updates).
  • .number - automatically converts input value to a number.
  • .trim - automatically trims whitespace from input value.
Example
<input v-model.lazy="search" />   <!-- syncs on blur/enter -->\n<input v-model.number="age" />    <!-- converts to number -->\n<input v-model.trim="username" /> <!-- trims whitespace -->
32

What is the Vue 3 KeepAlive component?

KeepAlive caches component instances when they are toggled off, preserving their state and avoiding re-mounting. Use include/exclude to control which components are cached. Cached components trigger onActivated/onDeactivated hooks.

Example
<KeepAlive :include="['UserList', 'Dashboard']" :max="10">\n  <component :is="currentView" />\n</KeepAlive>
33

What is the difference between onMounted and onBeforeMount?

  • onBeforeMount - called before the component is mounted. The template has been compiled but not yet inserted into the DOM. $el is not available.
  • onMounted - called after the component is mounted. The DOM is available. Use for DOM manipulation, third-party library initialization, and data fetching.
34

What is the Vue 3 Transition component?

The Transition component applies enter/leave animations to a single element or component. Uses CSS classes (v-enter-from, v-enter-active, v-enter-to, v-leave-from, v-leave-active, v-leave-to) or JavaScript hooks.

Example
<Transition name="fade">\n  <p v-if="show">Hello</p>\n</Transition>\n\n<style>\n.fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }\n.fade-enter-from, .fade-leave-to { opacity: 0; }\n</style>
35

What is the difference between Vue 3 slots and scoped slots?

  • Regular slots - parent passes HTML content to a child component. Child renders it with .
  • Scoped slots - child passes data back to the parent slot template. Enables the parent to customize rendering using child data.
Example
<!-- Child: scoped slot -->\n<slot :item="item" :index="index" />\n\n<!-- Parent: receives slot data -->\n<template #default="{ item, index }">\n  <span>{{ index }}: {{ item.name }}</span>\n</template>
36

What is the Vue 3 useTemplateRef() composable?

useTemplateRef() (Vue 3.5+) is the modern way to get a reference to a template element or component. It replaces the pattern of declaring a ref with the same name as the template ref attribute.

Example
<script setup>\nimport { useTemplateRef, onMounted } from "vue";\n\nconst inputEl = useTemplateRef("myInput");\nonMounted(() => inputEl.value.focus());\n</script>\n\n<template>\n  <input ref="myInput" />\n</template>
37

What is the difference between app.component() and local component registration?

  • Global (app.component()) - available in all templates throughout the app. Convenient but prevents tree-shaking.
  • Local (components option or script setup import) - only available in the registering component. Better for tree-shaking and explicit dependencies.
Example
// Global\napp.component("MyButton", MyButton);\n\n// Local (script setup - just import)\nimport MyButton from "./MyButton.vue";\n// MyButton is automatically available in template
38

What is the Vue 3 reactivity transform and why was it removed?

Reactivity Transform was an experimental feature that allowed using reactive variables without .value (using $ref, $computed macros). It was removed in Vue 3.4 due to confusion about when .value is needed. The standard ref() with .value is the recommended approach.

39

What is the difference between Vue 3 emit validation and unvalidated emits?

Validated emits use defineEmits with an object syntax to validate event payloads at runtime. Unvalidated emits just declare event names as strings. Validation helps catch bugs during development.

Example
const emit = defineEmits({\n  // No validation\n  click: null,\n  // With validation\n  submit: (payload) => {\n    if (!payload.email) {\n      console.warn("submit event missing email");\n      return false;\n    }\n    return true;\n  }\n});
40

What is the difference between Vue 3 server-side rendering (SSR) and static site generation (SSG)?

  • SSR - HTML rendered on the server per request. Better for dynamic, user-specific content. Use Nuxt.js.
  • SSG - HTML generated at build time. Fastest, best for content that rarely changes. Use Nuxt with static target or VitePress.
  • Both improve SEO and initial load performance compared to CSR.
41

What is Nuxt.js and what does it add to Vue?

Nuxt.js is a meta-framework built on Vue that adds: file-based routing, SSR/SSG/hybrid rendering, auto-imports (no need to import ref, computed, etc.), server API routes, layouts, middleware, and optimized production builds. It is to Vue what Next.js is to React.

42

What is the difference between Vue 3 v-memo directive?

v-memo memoizes a sub-tree of the template. It skips re-rendering the element and its children when the specified dependency array has not changed. Useful for optimizing large v-for lists.

Example
<div v-for="item in list" :key="item.id" v-memo="[item.id, item.selected]">\n  <!-- Only re-renders when item.id or item.selected changes -->\n  <p>{{ item.name }}</p>\n  <ExpensiveComponent :data="item" />\n</div>
43

What is the difference between Vue 3 errorCaptured and app.config.errorHandler?

  • onErrorCaptured() - lifecycle hook that catches errors from descendant components. Can return false to stop propagation.
  • app.config.errorHandler - global error handler for all uncaught errors in the app. Use for error reporting services (Sentry).
Example
app.config.errorHandler = (err, instance, info) => {\n  Sentry.captureException(err);\n  console.error(err);\n};
44

What is the Vue 3 useAttrs() and useSlotscomposable?

useAttrs() returns non-prop attributes passed to the component (class, style, event listeners not declared as props). useSlots() returns the slots object. Both are available in script setup without importing.

Example
<script setup>\nconst attrs = useAttrs(); // { class, style, onCustomEvent }\nconst slots = useSlots(); // { default, header }\n\n// Disable automatic attribute inheritance\ndefineOptions({ inheritAttrs: false });\n</script>
45

What is the difference between Vue 3 shallow rendering and full rendering in tests?

  • shallowMount() - renders the component with child components stubbed out. Faster, more isolated unit tests.
  • mount() - renders the full component tree including all children. Better for integration tests.
  • Use shallowMount for unit testing component logic; mount for testing component interactions.
Example
import { mount, shallowMount } from "@vue/test-utils";\n\nconst wrapper = mount(UserCard, {\n  props: { user: { name: "Alice" } }\n});\nexpect(wrapper.text()).toContain("Alice");
46

What is the difference between Vue 3 ref() and DOM refs?

  • Reactive ref() - holds reactive data values. Access via .value in JavaScript.
  • Template ref - a ref attribute on a DOM element or component gives direct access to the DOM node or component instance. Accessed via a ref() with the same name or useTemplateRef().
Example
<script setup>\nconst inputEl = ref(null); // template ref\nonMounted(() => inputEl.value.focus());\n</script>\n<template>\n  <input ref="inputEl" />\n</template>
47

What is the Vue 3 defineModel() macro?

defineModel() (Vue 3.4+) simplifies implementing v-model on a component. It creates a two-way binding automatically, replacing the manual defineProps + defineEmits pattern for v-model.

Example
<script setup>\nconst model = defineModel(); // replaces modelValue prop + update:modelValue emit\n</script>\n<template>\n  <input :value="model" @input="model = $event.target.value" />\n</template>\n\n<!-- Parent -->\n<MyInput v-model="username" />
48

What is the difference between Vue 3 onServerPrefetch and onMounted for SSR?

  • onMounted() - only runs on the client. Not called during SSR.
  • onServerPrefetch() - runs on the server during SSR. Use to pre-fetch data before the component is rendered on the server. The component waits for the returned Promise to resolve.
Example
onServerPrefetch(async () => {\n  // runs on server only\n  data.value = await fetchData();\n});\n\nonMounted(() => {\n  // runs on client only\n  initThirdPartyLib();\n});
49

What is the difference between Vue 3 app.config.globalProperties and provide/inject?

  • app.config.globalProperties - adds properties accessible in all component templates via this (Options API) or getCurrentInstance() (Composition API). Used for legacy plugins.
  • provide/inject - the recommended modern approach for sharing values across the component tree. Type-safe and explicit.
Example
// Legacy (globalProperties)\napp.config.globalProperties.$http = axios;\n\n// Modern (provide/inject)\napp.provide("http", axios);\n// In component:\nconst http = inject("http");
50

What is the difference between Vue 3 TransitionGroup and Transition?

  • Transition - animates a single element or component entering/leaving the DOM.
  • TransitionGroup - animates a list of elements. Supports move animations (v-move class) when items are reordered. Each child must have a unique key.
Example
<TransitionGroup name="list" tag="ul">\n  <li v-for="item in items" :key="item.id">{{ item.name }}</li>\n</TransitionGroup>\n\n<style>\n.list-enter-active, .list-leave-active { transition: all 0.3s; }\n.list-enter-from, .list-leave-to { opacity: 0; transform: translateX(30px); }\n.list-move { transition: transform 0.3s; }\n</style>

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.