Vue.js is a progressive JavaScript framework for building user interfaces. These questions cover core concepts, reactivity, components, lifecycle, Composition API, performance, and Vue 3 features commonly tested in frontend interviews.
Vue.js is a progressive JavaScript framework for building UIs and SPAs. Its core features include a reactive data-binding system, a component-based architecture, a virtual DOM, directives, and a gentle learning curve that allows incremental adoption.
v-if conditionally renders an element by adding or removing it from the DOM, while v-show always renders the element but toggles its CSS display property. Use v-if for infrequent toggles and v-show for frequent ones to avoid costly DOM operations.
Directives are special HTML attributes prefixed with v- that apply reactive behavior to the DOM. Built-in examples include v-bind, v-model, v-for, v-if, v-else, v-show, v-on, v-slot, and v-once.
Two-way data binding synchronizes the UI and component data automatically. v-model is syntactic sugar that combines v-bind (to bind a value) and v-on:input (to update the data), keeping the input and the data property in sync.
The lifecycle describes stages a component goes through from creation to destruction. Key hooks in Vue 3 are onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, and onUnmounted; in Vue 2 the equivalents are beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, beforeDestroy, and destroyed.
Computed properties are cached based on their reactive dependencies and only re-evaluate when those dependencies change, making them efficient for expensive calculations. Methods are re-executed every time the component re-renders, regardless of whether relevant data changed.
Props are custom attributes passed from a parent component to a child component to communicate data downward. You validate them by using the object syntax with type, required, default, and validator options instead of a plain array of strings.
Child components emit custom events using this.$emit('eventName', payload) in Vue 2 or the emit function from defineEmits in Vue 3. The parent listens with v-on (or @) on the child component tag and handles the event in a method.
The Composition API is an alternative way to write component logic using functions (setup, ref, reactive, computed, watch, etc.) instead of the Options API object. It was introduced in Vue 3 to improve logic reuse, TypeScript support, and code organization in large components.
ref wraps a single value (primitive or object) in a reactive wrapper accessed via .value, while reactive takes a plain object and returns a deeply reactive proxy without needing .value. Use ref for primitives and standalone values, reactive for structured state objects.
Watchers observe reactive data and run a callback when it changes. Use watch when you need to react to specific source changes and access the old value; use watchEffect when you want it to run immediately and automatically track all reactive dependencies accessed inside it.
Slots allow parent components to inject template content into child components. Default slots handle unnamed content, named slots allow multiple injection points via v-slot:name, and scoped slots expose child data back to the parent template through the slot's bindings.
Vue 3 uses ES6 Proxy to intercept property get/set operations on reactive objects, tracking which effects depend on each property during reads (track) and triggering re-runs when properties are mutated (trigger). This replaced the Object.defineProperty approach used in Vue 2, eliminating its limitations with array mutations and new property additions.
Vuex is a centralized state management library for Vue apps. Data flows unidirectionally: components dispatch Actions, which can handle async logic and commit Mutations, which synchronously modify State, which is then reflected reactively in the component's template via Getters or direct state access.
Pinia is the official recommended state management library for Vue 3, offering a simpler API with no mutations (only state, getters, and actions), first-class TypeScript support, and devtools integration. It eliminates boilerplate by allowing direct state mutation inside actions and supports modular stores without nested modules.
Vue Router is the official routing library that maps URL paths to components. Lazy loading is achieved by using dynamic imports in the route's component option — component: () => import('./views/MyPage.vue') — so the chunk is only fetched when the route is first visited.
Vue 3 introduced the Composition API, a Proxy-based reactivity system, the Teleport and Suspense built-in components, improved TypeScript support, multiple root elements (Fragments), and significant performance and tree-shaking improvements. Vue 2 relied on Object.defineProperty, the Options API, and required a single root element.
defineComponent is a helper that wraps a component options object to provide full TypeScript type inference without changing runtime behavior. It enables IDE autocompletion and type checking for props, emits, and the setup function when using TypeScript with the Options or Composition API.
Key strategies include lazy-loading routes and heavy components, using v-once for static content, keying v-for lists correctly, leveraging computed properties over methods, using shallowRef/shallowReactive for large non-deeply-reactive data, avoiding unnecessary watchers, and code-splitting with dynamic imports. Server-side rendering (Nuxt) or static site generation can also dramatically improve perceived performance.
Teleport renders a component's template content to a different DOM node outside the current component tree, specified by the to prop (e.g., body). It is useful for modals, tooltips, and notifications that need to escape overflow:hidden or z-index stacking contexts while keeping the logic co-located with the triggering component.
© RM Full Stack & AI Engineer · All interview questions · Roadmaps · Open the app