Beginner Level (0–1 Years)
1. What is the difference between `v-show` and `v-if` in Vue.js?
Answer:
`v-if` conditionally renders elements by adding or removing them from the DOM, which has a higher initial render cost but saves resources when the element is not needed. `v-show` always renders the element and toggles visibility using CSS (`display: none`), making it faster for frequent toggling but keeping the element in the DOM. Use `v-if` for conditions that rarely change and `v-show` for frequently toggled elements.
2. Can a single file component in Vue.js have multiple root elements?
Answer:
In Vue 2, a single-file component (SFC) must have a single root element, or it will cause a compilation error. In Vue 3, multiple root elements are supported using fragments, so you can have multiple elements directly under “ without a wrapping `
3. What will happen if you try to bind a non-existent property using `v-model`?
Answer:
In Vue 2, binding a non-existent property with `v-model` will not automatically make it reactive; you need to use `Vue.set` to add it reactively. In Vue 3, non-existent properties are not reactive unless defined in `data`, `ref`, or `reactive`. Attempting to bind a non-existent property may lead to unexpected behavior or errors unless properly initialized.
4. What is the Composition API, and how does it differ from the Options API in Vue.js?
Answer:
The Composition API, introduced in Vue 3, is a flexible way to organize component logic using functions like `ref`, `reactive`, and lifecycle hooks (e.g., `onMounted`). Unlike the Options API, which uses fixed properties (`data`, `methods`, `computed`), the Composition API allows logic to be grouped by feature, improving reusability and readability, especially in large components. The Options API is simpler for beginners but less flexible for complex apps.
5. What is the difference between `v-bind:class` and `:class` in Vue?
Answer:
There is no difference; `:class` is shorthand for `v-bind:class`. Both dynamically bind class data to an element.
6. Can you explain how Vue’s reactivity system works with arrays?
Answer:
In Vue 2, array mutation methods (`push`, `pop`, `splice`, etc.) are wrapped to be reactive, but direct index assignments (e.g., `array[1] = ‘new’`) are not. Use `Vue.set(array, index, value)` for reactivity. In Vue 3, Proxy-based reactivity makes direct index assignments reactive, simplifying array updates.
7. What is the difference between computed properties and methods in Vue?
Answer:
Computed properties are cached based on their reactive dependencies and only recompute when dependencies change. Methods run every time they’re called, regardless of dependency changes, which can impact performance. Computed properties are also inherently reactive, while methods are not.
8. If two components need to share state but are not parent-child, what’s a good solution in Vue?
Answer:
Use a state management library like Pinia (recommended for Vue 3) or Vuex (older, for Vue 2). These allow centralized state management for sharing data across components. Event buses, previously used in Vue 2, are deprecated in Vue 3.
9. Why doesn’t a DOM element update even though the data property it binds to has changed?
Answer:
This can happen if the data property isn’t reactive. In Vue 2, adding new properties to objects or arrays (e.g., `obj.newProp = value`) requires `Vue.set` for reactivity. In Vue 3, ensure properties are defined in `data`, `ref`, or `reactive`. Other causes include the element being conditionally rendered (`v-if`) and not in the DOM or lifecycle issues.
10. What happens if a `v-for` loop is missing a `key` attribute?
Answer:
Vue will render the list, but without a `key`, it cannot efficiently track elements, leading to DOM reuse issues, rendering bugs, or performance problems, especially in dynamic lists. Always use a unique `key` for predictable updates.
11. What is a potential issue when using `v-if` and `v-for` on the same element?
Answer:
Vue evaluates `v-for` before `v-if`, which can cause performance issues as the loop runs before the condition is checked. This is inefficient, especially for large lists. Move `v-if` to a wrapper element or use a computed property to filter the list before rendering.
12. How do you prevent a prop from being mutated in a child component?
Answer:
Create a local data copy of the prop or emit an event to the parent to update the prop instead of mutating it directly. In Vue 3’s Composition API, `defineProps` makes props read-only by default, enforcing this practice.
13. Why might a computed property not update even though its dependencies change?
Answer:
This can occur if dependencies are not reactive. In Vue 2, new properties added to objects or arrays aren’t reactive unless added with `Vue.set`. In Vue 3, ensure dependencies are defined with `ref` or `reactive`. Non-reactive dependencies or incorrect dependency tracking can also cause issues.
14. What’s wrong with using an arrow function for a Vue method?
Answer:
In the Options API, arrow functions don’t bind `this` to the Vue instance, making `this` undefined or pointing to the wrong context. Use regular functions for methods. In the Composition API, arrow functions are fine since `this` is not used.
15. Is it okay to modify a prop directly inside a child component?
Answer:
No, props should be treated as read-only. Mutating props directly violates Vue’s one-way data flow. Instead, use a local data copy or emit an event to request changes from the parent.
16. Why doesn’t `v-model` work on a custom component without additional code?
Answer:
`v-model` requires a `modelValue` prop and an `update:modelValue` event in Vue 3 (or `value` and `input` in Vue 2). Without these, `v-model` won’t bind correctly. Vue 3 also supports multiple `v-model` bindings for complex components.
17. How do you use `ref` and `reactive` in Vue 3, and when should you choose one over the other?
Answer:
In Vue 3’s Composition API, `ref` creates a reactive reference for a single value (e.g., `const count = ref(0)`), accessed with `.value`. `reactive` creates a reactive object (e.g., `const state = reactive({ count: 0 })`) for multiple properties. Use `ref` for primitive values or single variables, and `reactive` for objects with multiple properties to avoid excessive `.value` usage.
18. What’s the difference between `created` and `mounted` lifecycle hooks?
Answer:
`created` runs after the component instance is created but before DOM rendering, suitable for initializing data. `mounted` runs after the DOM is inserted, ideal for DOM manipulation. In the Composition API, use `onMounted` for `mounted` equivalent.
19. Can you access DOM elements in the `created` hook?
Answer:
No, the DOM is not rendered yet in the `created` hook. Use the `mounted` hook (or `onMounted` in Composition API) for DOM access.
20. What is a common mistake when binding to an input using `v-model` with a `number`?
Answer:
Input values are strings by default. Using `v-model.number` coerces the value to a number, but invalid inputs (e.g., empty strings) may still return a string or `NaN`. Always validate or manually convert using `parseInt()` or `Number()`.
21. What is the purpose of two-way binding in Vue 3, replacing the `.sync` modifier?
Answer:
In Vue 3, `v-model` replaces the `.sync` modifier for two-way binding. It binds a `modelValue` prop and listens for an `update:modelValue` event to update the parent. In Vue 2, `.sync` simplified two-way binding by emitting `update:propName`. Use `v-model` in Vue 3 for consistency.
22. What are slots in Vue.js, and how do they help with component reusability?
Answer:
Slots are placeholders in a Vue component’s template that allow parent components to inject custom content. Defined with the “ tag, they make components reusable by letting parents customize parts of the child’s template. For example, a “ component can use a slot for its content, allowing different parents to insert unique text or elements.
23. What’s a subtle bug when using `v-bind:style=”{ width: myWidth + ‘px’ }”` if `myWidth` is undefined?
Answer:
If `myWidth` is undefined, it results in `width: ‘undefinedpx’`, an invalid CSS value. Use a computed property or ternary operator (e.g., `width: myWidth ? myWidth + ‘px’ : ‘auto’`) to ensure valid CSS.
24. What’s the downside of using inline event handlers like `@click=”doSomething()”`?
Answer:
Inline handlers create a new function on each render, which may slightly impact performance in large lists or frequent updates. For most cases, the impact is minimal, but defining methods explicitly can improve clarity and maintainability.
25. Why might a deeply nested object not trigger reactivity when updated?
Answer:
In Vue 2, new properties on nested objects aren’t reactive unless added with `Vue.set`. In Vue 3, Proxy-based reactivity handles nested objects better, but properties must still be defined in `reactive` or `ref` objects to ensure reactivity.
👋 Need top Vue.js developers for your project? Interview this week!
Fill out the form to book a call with our team. We’ll match you to the top developers who meet your requirements, and you’ll be interviewing this week!
Intermediate Level (1–3 Years)
1. How does the Composition API improve code organization in Vue 3?
Answer:
The Composition API groups related logic by feature (e.g., `useCounter` for counter-related state and methods) rather than by type (`data`, `methods`), reducing code duplication, improving testability, and making large components or reusable logic easier to maintain compared to the Options API.
2. How do you share logic across components using the Composition API?
Answer:
Create composables (e.g., `useFetch` for API calls or `useCounter` for counter logic) as reusable functions that encapsulate reactive state and logic. Import and call them in a component’s `setup()` or `script` to share functionality across components.
3. What is the purpose of `defineProps` and `defineEmits` in Vue 3?
Answer:
`defineProps` declares incoming props, and `defineEmits` declares events a component emits, both used in `script setup` syntax for concise Composition API code. They simplify prop and event definitions without needing a full `setup()` function.
4. Why should you avoid mutating Vuex state outside of mutations?
Answer:
Mutating Vuex state outside mutations bypasses Vuex’s state tracking and devtools, causing unpredictable behavior and debugging issues. In Vue 3, Pinia is preferred, but it also enforces mutations via actions for consistency.
5. What happens when you use `v-model` on a custom component without specifying a `modelValue` prop?
Answer:
Vue cannot bind the value correctly. In Vue 3, `v-model` expects a `modelValue` prop and an `update:modelValue` event. Without these, the binding fails, and the component won’t update reactively.
6. How would you optimize performance for a list rendered with `v-for`?
Answer:
Use a unique `key` for efficient DOM updates, avoid complex logic in templates, use computed properties for filtering, implement pagination or virtual scrolling (e.g., with `vue-virtual-scroller`), and use “ to cache components.
7. How can you dynamically register components in Vue?
Answer:
Register components dynamically using the `components` option for local registration or `app.component()` for global registration. Use the “ tag with dynamic imports or `defineAsyncComponent` for lazy loading.
8. What’s the difference between `watch` and `watchEffect` in Vue 3?
Answer:
`watch` explicitly tracks specific reactive sources (e.g., `ref` or `reactive`) with options like `deep` or `immediate`. `watchEffect` automatically tracks all reactive dependencies used in its callback, running immediately and on dependency changes.
9. What is a render function and when would you use one?
Answer:
Render functions create components programmatically in JavaScript using `h()` instead of templates. Use them for dynamic layouts, third-party integrations, or scenarios requiring complex rendering logic not easily achieved with templates.
10. How do transitions work with `v-if` and `v-show`?
Answer:
`v-if` transitions elements in/out of the DOM, while `v-show` transitions visibility using CSS (`display: none`). Both require wrapping in “ or “ for animation with CSS or JavaScript hooks.
11. How do you manage side effects in Vue 3’s Composition API?
Answer:
Use `watch` or `watchEffect` to react to changes, and lifecycle hooks like `onMounted` for initialization. For cleanup, return a function from `watchEffect` or use `onUnmounted` to handle side effects like timers or subscriptions.
12. How does `shallowReactive` differ from `reactive`?
Answer:
`shallowReactive` tracks reactivity only at the root level of an object, not nested properties, improving performance when deep reactivity isn’t needed. `reactive` tracks all nested properties.
13. Why should you avoid using `Math.random()` inside a computed property?
Answer:
Computed properties are cached and only recompute when dependencies change. `Math.random()` introduces non-deterministic values, causing stale or inconsistent results. Use a method or `watchEffect` for random values.
14. What is the purpose of `$attrs` in Vue 3?
Answer:
`$attrs` provides access to non-prop attributes and event listeners passed from a parent, including events (unlike Vue 2, where `$listeners` was separate). Use it to forward attributes to child elements.
15. How does the `teleport` component work?
Answer:
“ renders a component’s template to a different DOM location using the `to` attribute (e.g., “). It’s useful for modals, popovers, or elements needing to escape their parent’s DOM context.
16. How would you debug a watcher that never triggers?
Answer:
Ensure the watched property is reactive (e.g., defined in `data`, `ref`, or `reactive`). In Options API, verify the watcher is in the `watch` option. In Composition API, check `watch` or `watchEffect` sources and ensure the component is mounted.
17. What’s the difference between `computed` and `ref` when returning values from a Composition API function?
Answer:
`ref` stores a single reactive value, accessed via `.value`, while `computed` defines a cached, derived value that recomputes only when its dependencies change. Use `computed` for derived state, `ref` for direct state.
18. When might `ref` be preferred over `reactive`?
Answer:
Use `ref` for primitive values (e.g., strings, numbers) or single reactive variables, as it’s simpler to manage. Use `reactive` for objects or collections with multiple properties to avoid excessive `.value` access.
19. What is the reactivity caveat when using `Object.freeze()` in Vue?
Answer:
Frozen objects are not reactive, as `Object.freeze()` prevents mutations. Vue warns if you use `Object.freeze()` with `reactive` or `ref`, as changes cannot be tracked.
20. Can you create a global component inside a Composition API file?
Answer:
No, global registration is done with `app.component()` during app setup, not within a component’s `script setup` or `setup()`. The Composition API focuses on local component logic.
21. How does Vue handle two-way binding internally with `v-model`?
Answer:
`v-model` is syntactic sugar for a `modelValue` prop (Vue 3) or `value` (Vue 2) and an `update:modelValue` (or `input`) event. Vue syncs the prop and event to enable two-way data binding.
22. What is tree-shaking and how does Vue 3 support it?
Answer:
Tree-shaking removes unused code during bundling with tools like Vite or Webpack. Vue 3’s ES module-based structure enables tree-shaking of unused features (e.g., directives, transitions), reducing bundle size.
23. How do you use multiple `v-model` bindings on a single component in Vue 3?
Answer:
Vue 3 supports multiple `v-model` bindings using arguments, e.g., “. The component defines `title` and `content` as props and emits `update:title` and `update:content` events.
24. What is the use of `provide` and `inject` in Vue?
Answer:
`provide` allows a parent to share data or methods with descendants, and `inject` lets descendants access them without prop drilling. Use `ref` or `reactive` with `provide` for reactive data sharing.
25. When should you use `watchEffect` instead of `watch`?
Answer:
Use `watchEffect` when you don’t know specific dependencies upfront, as it tracks all reactive dependencies automatically. Use `watch` for explicit control over specific sources with options like `deep` or `immediate`.
26. How do you use `v-once` and what’s a potential drawback?
Answer:
`v-once` renders an element once and skips future updates, improving performance for static content. The drawback is that changes to bound data won’t update the UI.
27. Can you explain lazy loading components in Vue?
Answer:
Lazy load components using dynamic imports, e.g., `const MyComponent = () => import(‘./MyComponent.vue’)`, or `defineAsyncComponent` for advanced control like loading states. This reduces initial bundle size.
28. Why is it risky to use `index` as a `key` in a `v-for` loop?
Answer:
Using `index` as a `key` causes issues when list items change order, as Vue cannot track individual elements, leading to incorrect DOM reuse or rendering bugs. Use unique IDs instead.
29. How do you call a method from a parent component?
Answer:
You can’t directly call parent methods from a child. Instead, emit an event from the child and handle it in the parent, or use `provide`/`inject` to share methods across components.
30. How do `setup()` and the Options API co-exist in the same component?
Answer:
`setup()` runs before Options API properties like `data` and `methods`. They can co-exist, but `this` is undefined in `setup()`, so avoid accessing Options API properties there. Use `script setup` for simpler integration.
31. What’s the caveat with accessing refs returned by `setup()`?
Answer:
Refs returned from `setup()` in an object are not automatically unwrapped in templates, requiring `.value`. In `script setup`, refs are auto-unwrapped for convenience.
32. What is the use of `emit` in the Composition API?
Answer:
`emit` triggers custom events from a component, available as the second argument in `setup(props, { emit })` or via `defineEmits` in `script setup`. Example: `emit(‘update:modelValue’, newValue)`.
33. How do you test Vue components that use asynchronous code?
Answer:
Use testing libraries like Vue Test Utils or Testing Library. For async code, use `flushPromises()` or `await wrapper.vm.$nextTick()` to wait for promises and reactivity updates before asserting results.
34. How can a child component access slot props passed by the parent?
Answer:
Slot props are accessed via the `v-slot` directive’s scope, e.g., `{{ slotProps.data }}`. The parent passes props through the slot’s binding.
35. What are functional components and when are they useful?
Answer:
Functional components are stateless and instanceless, defined with a render function. They’re lightweight but less common in Vue 3 due to the Composition API’s flexibility. Use them for simple, performance-critical UI elements.
36. What happens if a component mutates a prop directly?
Answer:
Vue warns against mutating props, as they should be immutable to maintain one-way data flow. Direct mutation can cause unpredictable behavior and break parent-child synchronization.
37. Can you use Composition API features in a Vue 2 project?
Answer:
Yes, using Vue 2.7 or the `@vue/composition-api` plugin, but Vue 3 is the standard for new projects. The Composition API in Vue 2 mimics Vue 3’s functionality for migration purposes.
38. How would you access the root Vue instance from a child?
Answer:
Use `this.$root` in Options API or `getCurrentInstance().proxy.$root` in Composition API, but avoid it to prevent tight coupling. Prefer Pinia or `provide`/`inject` for data sharing.
39. How do you force a component to re-render?
Answer:
Change the `:key` on the component’s root element to force re-creation, as Vue treats different keys as new components. Example: “.
40. What is the `expose()` method in Vue 3?
Answer:
`expose()` in the Composition API explicitly defines which properties or methods a component exposes to its parent via `ref`. It prevents exposing the entire internal scope, improving encapsulation.
41. What’s the difference between local and global component registration?
Answer:
Local registration in a component’s `components` option limits its scope to that component. Global registration with `app.component()` makes the component available app-wide, increasing bundle size if overused.
42. What’s a caveat of using `v-if` with an async component?
Answer:
The async component may not be loaded when `v-if` evaluates, causing errors or blank renders. Use `defineAsyncComponent` with `loadingComponent` and `errorComponent` for better handling.
43. Can you nest `watch` inside `setup()`?
Answer:
Yes, `watch()` can be called inside `setup()` to monitor reactive properties like `ref` or `reactive`. It’s commonly used to handle side effects or state changes within the Composition API.
44. How does the `ref` attribute in Vue.js templates help access elements or components?
Answer:
The `ref` attribute assigns a reference to a DOM element or Vue component in a template, allowing direct access to it in the component’s logic. In the Options API, you access the reference through the component’s `$refs` property. In the Composition API, within a `setup` function or `script setup`, you define a reactive reference variable initialized as null to store the element or component instance. For example, assigning a `ref` to a div or child component lets you interact with its properties or methods, such as focusing an input or calling a component’s function, once the template is rendered.
45. What are the advantages of Pinia over Vuex for state management in Vue 3?
Answer:
Pinia is lighter, has a simpler API, and is designed for Vue 3’s Composition API. It uses `ref` and `reactive` for state, eliminates boilerplate (no mutations required), and offers better TypeScript support. Vuex, while robust, is more verbose and better suited for Vue 2 or legacy projects.
46. What is SSR and why is hydration important in Vue?
Answer:
Server-Side Rendering (SSR) pre-renders pages on the server for faster initial load and SEO. Hydration attaches the client-side Vue app to the server-rendered HTML, adding reactivity and event listeners without re-rendering the DOM.
47. How would you animate a list with `v-for`?
Answer:
Wrap the `v-for` loop in a “ component, define `move`, `enter`, and `leave` transitions using CSS classes or JavaScript hooks to animate list changes smoothly.
48. How do you memoize expensive computed values?
Answer:
Computed properties are memoized by default, recomputing only when dependencies change. Ensure minimal dependencies in the computed function to optimize performance and avoid unnecessary recalculations.
49. How do you handle errors in async composables in Vue 3?
Answer:
Use try-catch blocks within async composables to capture errors, and return an error state (e.g., `ref(null)`) to the component. Example: const error = ref(null); try { await fetchData(); } catch (e) { error.value = e.message; }
. Components can then react to `error` for user feedback.
50. Can a single Vue app contain multiple root Vue instances?
Answer:
Yes, but it’s discouraged due to state fragmentation. Use cases like micro-frontends may justify it. Prefer a single root instance with dynamic components or “ for layout management.

Hire Top LATAM Developers: Guide
We’ve prepared this guide that covers benefits, costs, recruitment, and remote team management to a succesful hiring of developers in LATAM.
Fill out the form to get our guide.
Advanced Level (3+ Years)
1. How does Vue 3’s Proxy-based reactivity system improve over Vue 2’s Object.defineProperty?
Answer:
Vue 3’s Proxy-based reactivity tracks property additions, deletions, and nested objects automatically, unlike `Object.defineProperty`, which requires manual iteration and has caveats like non-reactive new properties. Proxies enable better array handling and dynamic reactivity but may have slightly higher overhead for simple objects.
2. What is the significance of `markRaw` and `toRaw` in Vue 3?
Answer:
`markRaw` prevents an object from becoming reactive, ideal for non-reactive libraries like Lodash or complex class instances. `toRaw` retrieves the original object from a reactive proxy, useful for debugging or passing non-reactive data to external APIs.
3. How does the Suspense component in Vue 3 work and when should it be used?
Answer:
“ renders fallback content while async components or `setup()` promises resolve. It’s ideal for code-splitting, SSR, or async data fetching. Nested Suspense boundaries allow granular control, and `errorCaptured` handles errors during async resolution.
4. How does Vue handle rendering optimization using the patch flag system?
Answer:
Vue 3’s compiler adds patch flags to templates, marking dynamic parts (e.g., props, text) for targeted updates. This skips unnecessary virtual DOM diffs, improving performance by focusing only on changed reactive dependencies.
5. Explain the difference between `readonly` and `shallowReadonly` in Vue 3.
Answer:
`readonly` makes an entire object deeply immutable, preventing all mutations. `shallowReadonly` only restricts root-level properties, allowing nested properties to remain reactive and mutable, useful for controlled API exposure.
6. How do you handle memory leaks in large-scale Vue applications?
Answer:
Use `onUnmounted` to clean up intervals, event listeners, or subscriptions. Group reactive effects with `effectScope` for bulk teardown. Avoid excessive watchers, dereference large objects, and profile memory with Vue Devtools or browser tools to detect retained closures or DOM nodes.
7. What are virtual DOM performance bottlenecks, and how can they be mitigated?
Answer:
Bottlenecks include frequent large DOM diffs, key mismanagement, and deep reactive structures. Mitigate by flattening templates, using `v-once`, `v-memo` with dependency arrays, splitting components, and avoiding unnecessary reactivity with `markRaw`.
8. How does Vue SSR differ from traditional client-side rendering?
Answer:
SSR pre-renders HTML on the server for faster initial load and SEO, then hydrates on the client for interactivity. It adds complexity for state management and hydration mismatches. Frameworks like Nuxt 3 simplify SSR implementation.
9. Explain hydration mismatch and how to avoid it in Vue SSR?
Answer:
Hydration mismatches occur when server-rendered HTML differs from client-rendered DOM, often due to client-only logic or third-party scripts. Avoid by using “, ensuring server-client symmetry, deferring scripts to `onMounted`, and debugging with Vue Devtools or console warnings. Nested Suspense boundaries require consistent fallback logic.
10. What is the role of `getCurrentInstance()` in advanced Composition API use?
Answer:
`getCurrentInstance()` provides access to the component’s internal instance, including `proxy`, `attrs`, `slots`, or `appContext`. Use it for plugins or advanced logic, but avoid overuse in favor of composables for maintainability.
11. How do you implement a plugin system in Vue 3?
Answer:
Create a plugin with an `install` method that receives the `app` instance. Register global components, directives, or `provide` injections. Use TypeScript for typed plugins and limit scope to avoid global pollution.
12. How do you optimize Vue apps for Time to Interactive (TTI)?
Answer:
Use code-splitting with async components, lazy load routes, defer non-critical rendering with “, and reduce bundle size via tree-shaking with ES module bundlers (e.g., Vite). In SSR, use streaming and inline critical CSS with “.
13. What’s the difference between `v-memo` and `v-once`?
Answer:
`v-once` renders an element once and never updates. `v-memo` caches subtrees and re-renders only when specified reactive dependencies change, offering fine-grained control for conditional template updates.
14. Describe the lifecycle of a component rendered in a “ wrapper.
Answer:
“ shows the fallback slot while async `setup()` or components resolve. Once resolved, it renders the default slot, triggering `onMounted` and `onUpdated`. Nested Suspense boundaries cascade, with each resolving independently, affecting lifecycle hook timing.
15. How do you architect a Vue 3 app to scale across multiple teams?
Answer:
Use micro-frontends, isolate logic in composables, enforce type safety with TypeScript, and share UI via component libraries. Use monorepo tools like Nx or Lerna for shared code and build management, with clear API boundaries for team collaboration.
16. How do reactivity limitations impact custom class instances in Vue?
Answer:
Vue cannot observe class prototype properties or dynamically added properties. Use `markRaw` to exclude classes from reactivity or wrap primitive properties in `ref`/`reactive` for controlled reactivity.
17. How would you isolate reactive state for unit testing?
Answer:
Extract logic into composables returning `ref` or `reactive` objects. Test them independently using Vitest or Jest, mocking dependencies with `vi.mock` or `jest.mock`. Avoid `getCurrentInstance` or global context to ensure test isolation.
18. What are some potential pitfalls of global mixins?
Answer:
Global mixins affect all components, risking side effects, naming conflicts, and debugging issues. Vue 3 discourages them in favor of composables for modular, scoped logic reuse.
19. Explain the benefits and limitations of using `script setup` syntax.
Answer:
` script` reduces boilerplate, improves readability, and enhances TypeScript inference. Limitations include no access to `this`, challenges with dynamic instance injection, and less flexibility for complex Options API logic.
20. How would you implement an accessible and keyboard-navigable modal component in Vue?
Answer:
Use focus traps, `aria` attributes, `tabindex`, and `keydown` listeners for ESC. Set `role=”dialog”` and return focus on close. Wrap in “ and lock scroll. Test with tools like axe-core for accessibility compliance.
21. How can you debug performance issues in large Vue applications?
Answer:
Use Vue Devtools to track component updates and reactivity graphs. Profile First Contentful Paint (FCP) and Largest Contentful Paint (LCP) with browser tools. Identify excessive re-renders, deep watchers, or costly computed properties.
22. What are the benefits of using `defineExpose` in `script setup`?
Answer:
`defineExpose` selectively exposes properties or methods to the parent via `ref`, enhancing encapsulation by preventing unintended access to internal component state.
23. How can you dynamically control the hydration process in SSR?
Answer:
Use `v-cloak`, “, or Suspense to defer hydration for specific components. Return promises in `setup()` to control timing, ensuring server and client render the same DOM structure.
24. How does the “ directive assist in dynamic component rendering?
Answer:
“ dynamically renders a component or HTML tag based on a variable, e.g., “. It supports polymorphic rendering for flexible UI composition.
25. Explain how `v-memo` helps with optimizing conditional templates.
Answer:
`v-memo` caches subtrees, re-rendering only when specified reactive dependencies change. It reduces DOM diffing for stable sections, improving performance in complex templates.
26. How would you handle shared state without Vuex or Pinia?
Answer:
Create a composable exporting `ref` or `reactive` state, acting as a lightweight global store. Use `provide/inject` for scoped sharing, but monitor reactivity overhead for large datasets.
27. How do you integrate TypeScript with Vue 3 for type-safe components?
Answer:
Use `script setup lang=”ts”` for type-safe `defineProps` and `defineEmits`. Define prop types with `defineProps<{ propName: Type }>`, and use `withDefaults` for defaults. For composables, return typed `ref` or `reactive` objects, leveraging Vue’s `PropType`_origins/master/PropType.ts and interfaces for complex prop validation.
28. How does Vue handle component updates when reactive state is mutated?
Answer:
Vue tracks reactive dependencies during rendering. When a `ref` or `reactive` value changes, Vue re-renders dependent components, using patch flags to minimize virtual DOM diffs and apply targeted updates.
29. How does `teleport` differ from third-party portal solutions?
Answer:
“ is Vue 3’s native solution for rendering content outside the component hierarchy, replacing plugins like `portal-vue`. It uses the `to` attribute to target DOM nodes, ideal for modals or overlays.
30. How do you implement route-based code splitting in Vue Router?
Answer:
Use dynamic imports in route config, e.g., `{ path: ‘/admin’, component: () => import(‘./AdminView.vue’) }`. This lazy-loads components only when the route is accessed, reducing initial bundle size.
31. What architectural pattern would you use for multi-tenant Vue applications?
Answer:
Use micro-frontends with shared design systems, isolate tenant configs via environment-based loading, and dynamically register tenant-specific routes and stores based on authentication context to ensure state separation.
32. How would you create a plugin that exposes a reactive global service?
Answer:
Create a composable with `ref` or `reactive` state, expose it via `app.provide(‘key’, value)`, and use `inject()` in components. This ensures reactivity and testability without global scope pollution.
33. How do you optimize Vue apps for Time to Interactive (TTI)?
Answer:
Use code-splitting with async components, lazy load routes, defer non-critical rendering with “, and reduce bundle size via tree-shaking with ES module bundlers (e.g., Vite). In SSR, use streaming and inline critical CSS with “.
34. What is the use of `appContext` and when would you access it?
Answer:
`appContext` holds global app data like `config`, `provides`, and plugins. Access it via `getCurrentInstance().appContext` for reading shared services or global injections in advanced plugin logic.
35. What are advanced testing strategies for Vue components?
Answer:
Use Vitest or Jest with Vue Test Utils for unit tests, mocking composables and Pinia stores. Stub child components with `shallowMount` for isolation. For end-to-end testing, use Cypress or Playwright to simulate user flows, and test accessibility with axe-core. Mock async APIs with MSW (Mock Service Worker).
36. How do you measure hydration performance in Vue SSR?
Answer:
Use `performance.mark` and `PerformanceObserver` to measure hydration timing. Vue Devtools shows SSR hydration metrics. Tools like Lighthouse provide First Contentful Paint and Time to Interactive metrics for optimization.
37. What is the `effectScope` API and what problem does it solve?
Answer:
`effectScope` groups reactive effects (watchers, computed) into a single scope for collective teardown, preventing memory leaks by explicitly stopping all effects when a component or feature is destroyed.
38. What are `customRef`s and when would you use one?
Answer:
`customRef` creates a ref with custom get/set logic, e.g., for debounced inputs or throttled updates. Use it for controlled reactivity in forms or rate-limited API syncs.
39. How does dependency injection via `provide/inject` differ from `props`?
Answer:
`props` are explicit, reactive, and limited to parent-child relationships. `provide/inject` enables implicit data sharing across the component tree, ideal for global configs or services.
40. How would you expose dynamic runtime configuration in a Vue app?
Answer:
Fetch config JSON at app startup, store in a reactive store or `app.provide()`, and access via `inject()`. Sanitize inputs to prevent security risks like XSS from untrusted configs.
41. How do you handle complex state transitions in Pinia for Vue 3?
Answer:
Use Pinia actions for async state transitions, combining `ref` and `reactive` for state management. Implement state machines with XState, or handle loading/error states with `ref` flags. Use `watch` or `watchEffect` in components to react to changes.
42. How does Vue’s `v-model` differ between native inputs and custom components?
Answer:
For native inputs, `v-model` syncs `value` and `input` events. For components, it requires a `modelValue` prop and `update:modelValue` event, allowing custom binding logic.
43. How would you test a component using Suspense and async setup?
Answer:
Use Vitest or Testing Library with `flushPromises()` to resolve async `setup()` logic. Assert fallback and resolved DOM states, mocking timeouts or APIs with MSW to simulate delays.
44. What are advanced patterns for SSR state hydration in Vue?
Answer:
Inject serialized server state into a `script` tag, then rehydrate Pinia stores or composables on the client. Use `provide/inject` or global stores to ensure consistent state across server and client.
45. What challenges arise with reactive maps or sets in Vue?
Answer:
Vue’s reactivity doesn’t deeply observe `Map`/`Set` internals. Use `reactive(new Map())` and trigger updates via computed properties or explicit `watch` to handle changes.
46. How do `shallowRef` and `triggerRef` help in optimization?
Answer:
`shallowRef` limits reactivity to the root value, avoiding overhead for nested properties. `triggerRef` manually forces updates for non-reactive changes, optimizing large or external objects.
47. How would you implement a plugin with lifecycle awareness?
Answer:
Use `app.provide()` to inject a composable with lifecycle hooks like `onMounted` or `onUnmounted`. Avoid `app.mixin()`; prefer composables for modular, lifecycle-aware logic.
48. What is a computed getter/setter and why use it?
Answer:
A computed property with `get` and `set` methods enables two-way binding with transformation logic, useful for form inputs or derived state requiring controlled updates.
49. How do you optimize Vue apps for Time to Interactive (TTI)?
Answer:
Use code-splitting with async components, lazy load routes, defer non-critical rendering with “, and reduce bundle size via tree-shaking with ES module bundlers (e.g., Vite). In SSR, use streaming and inline critical CSS with “.
50. What are common anti-patterns in large Vue codebases?
Answer:
Anti-patterns include overusing watchers instead of computed properties, deep reactive trees, global state mutations, tightly coupled components, and reliance on mixins. Favor composables, scoped logic, and testable patterns.