
This article summarizes a list of Vue.js interview questions that I would ask candidates and that I get often asked in interviews.
Vue is a progressive framework for building user interfaces that was designed to be incrementally adoptable. Its core library is focused exclusively on the view layer so that it can easily be integrated with other projects or libraries.
But in contrast to React, Vue provides companion libraries for routing and state management which are all officially supported and kept up-to-date with the core library.
Vue.js combines the best parts of Angular and React. Vue.js is a more flexible, less opinionated solution than Angular but it's still a framework and not a UI library like React
I recently decided to focus my freelancer career on Vue.js, you can read more about this decision in the corresponding blog post.
Vue Single File Components (aka *.vue files, abbreviated as SFC) is a special file format that allows us to encapsulate the template (<template>), logic (<script>), and styling (<style>) of a Vue component in a single file.
Vue SFC is a framework-specific file format and must be pre-compiled by @vue/compiler-sfc into standard JavaScript and CSS. A compiled SFC is a standard JavaScript (ES) module.
Computed properties should be used to remove as much logic as possible from the templates as otherwise the template gets bloated and is harder to maintain. If you have complex logic including reactive data in your template you should use a computed property instead.
Instead of methods, computed properties are cached based on their reactive dependencies. A computed property will only re-evaluate when some of its reactive dependencies have changed.
Watchers are a more generic way to react to data changes instead of using computed properties.
They should be used when asynchronous or expensive operations need to be executed in response to changing data.
If a component is registered globally it can be used in the template of any component instance within this application:
const app = Vue.createApp({})
app.component('component-a', {
/* ... */
})
app.mount('#app')
Global registration can unnecessarily increase your JavaScript bundle if you are using build systems like Webpack. If you stop using a component in your code, it will still be included in the final build.
To avoid this, we can register components locally by defining them in the component where it is needed:
import ComponentA from './ComponentA.vue'
export default {
components: {
ComponentA,
},
// ...
}
Note that locally registered components are not available in subcomponents.
Here you can find all available directives.
The application instance is used to register globals that can then be used by components within that application. An application instance is created with the createApp:
const app = Vue.createApp({
/* options */
})
In Vue 2 this was called Vue instance and created this way:
const vm = new Vue({
// options
})

Vue uses a one-way data flow. Parents can pass data to child components using a prop and bind the data using the v-bind directive. When the parent component updates the prop value, it's automatically updated in the child component. You should avoid mutating the property inside the child component and it will not affect the property in the parent component (unless it's an array or object). Using Events the child component can communicate back to the parent.
Vue provides the v-model directive for two-way data binding of form inputs. v-model is just syntax sugar for v-bind combined with v-on:input. But you can also implement v-model for your custom components, take a look at "Using v-model on Components" for more details.
A slot is a placeholder in a child component that is filled with content passed from the parent. Content of a regular slot is compiled in the parent’s scope and then passed to the child component.
Scoped slots are needed if the slot content needs to have access to data only available in the child component. We can bind attributes a <slot>, these elements are called slot props. Now, in the parent scope, we can use v-slot with a value to define a name for the slot props we've been provided:

Vue uses an unobtrusive reactivity system which is one its most distinct features.
But what is reactivity? Reactivity is a programming paradigm that allows us to adjust to changes in a declarative manner.
The official documentation uses an Excel spreadsheet to demonstrate reactivity:
As you can see, we get the SUM if we put the number 2 in the first cell and number 3 in the second cell. The reactive part happens if we update the first number and the SUM automatically gets updated too.
Unfortunately, JavaScript variables are not reactive by default:
let value1 = 1
let value2 = 2
let sum = value1 + value2
console.log(sum) // 5
value1 = 3
console.log(sum) // Still 5
Therefore, Vue 3 added an abstraction on JavaScript Proxy to be able to achieve the reactiveness.
In Vue 3, we can easily declare a reactive state using the reactive method
import { reactive } from 'vue'
// reactive state
const state = reactive({
count: 0,
})
or create standalone reactive values as refs:
import { ref } from 'vue'
const count = ref(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
In Vue 2 and 3 we can use Mixins to reuse code between components.
Since Vue 3 the framework provides the Composition API that resolves the Mixins drawbacks.
There are multiple reasons why your Vue application may become slow:
This article provides the solution to the above-mentioned performance issues.
Each Vue component instance goes through a series of initialization steps when it's created. For example, it needs to set up data observation, compile the template, mount the instance to the DOM, and update the DOM when data changes. Along the way, it also runs functions called lifecycle hooks, which allows us to execute custom code at specific stages.
beforeCreate and created) allow us to perform actions before the component has even been added to the DOM. These hooks are also executed during server-side rendering. The created hook is the perfect lifecycle hook to trigger HTTP requests and populate any initial data that the component needs.beforeMount, mounted) are often the most-used hooks and allow us to access the component immediately before and after the first render. The mounted hook is an ideal time to integrate 3rd party libraries or to access the DOM.beforeUpdate, updated) are called whenever a reactive property used by the component changes, or something else causes it to re-render. In the updated hook the DOM and the model are in-sync while in the beforeUpdate hook only the model is updated but not the DOM.beforeDestroy, destroyed) allow us to perform actions when the component is destroyed, such as cleanup or sending analytics. In the beforeDestroy hook we still have access to the Vue instance and can, for example, emit events. destroyed is the ideal place for a final cleanup, e.g. removing event listeners.Below is a diagram for the instance lifecycle:
There exists an additional interesting lifecycle hook called errorCaptured which is called when an error from any descendent component is captured.
This hook receives three arguments: the error, the component instance that triggered the error, and a string containing information on where the error was captured. The hook can return false to stop the error from propagating further.
Of course, this list does not guarantee that you will pass an upcoming Vue job interview. There are hundreds of questions that you might get asked in such an interview. I recommend reading the official docs and take some courses on Vue Mastery if you prefer video courses.
Let me know in the comments if you would ask any other important questions about Vue.
If you liked this article, follow me on Twitter to get notified about new blog posts and more content from me.
Alternatively (or additionally), you can also subscribe to my newsletter.
