Quick Summary
This comprehensive guide will walk you through everything you need to know about migrating from Vue 2 to Vue 3. Whether you are new to Vue or a seasoned developer, you will gain a clear understanding of the key differences, enhancements, benefits, and a step-by-step tutorial to successfully transition your Vue 2 applications to Vue 3.
Several developers are still working on using Vue.js 2 as their primary framework, but with the release of Vue 3, upgrading has become an important step to improve performance. Moreover, it offers better TypeScript support and long-term maintainability, boosting your web applications.
However, the migration process can feel complex and frustrating, especially for those who are unfamiliar with it. To make things easier, we have created a detailed, beginner-friendly tutorial that guides you through Vue 2 to Vue 3 migration step by step.
Also, this comprehensive tutorial designed to eliminate confusion and help you transition smoothly, even starting from scratch. Utilizing the right approach and tools, migrating can be a rewarding and manageable process. Let’s dive deep into how it can benefit your Vue JS applications.
The IT industry evolves with time, as does the technology and its technical requirements. Keeping the project updated is inevitable, even if one of your technologies from the tech stack has been modernized.
This is because whenever technology evolves, it updates its dependencies and libraries, removes unwanted garbage code, and adds new features that enhance development and workflow.
Vue 3 is the new technology update and there’s no need to update your entire Vue 2 project to Vue 3 immediately. However, if you start planning it out because as time passes, lesser third-party libraries will support version 2, and maybe VueJS will not lower the development support for version 2.
VueJs 3 is written from scratch and comes with even better performance, better tree-shaking, smaller size, improved TypeScript support, and many new features for developing large-scale enterprise software.
Before we begin the Vue 2 to Vue 3 migration process, it’s essential to understand the differences between the two versions and the improvements implemented in Vue 3.
The major differences between Vue 2 and Vue3 lie in terms of technical features such as creating a new application, handling multiple roots, utilizing the composition API, teleporting, implementing life cycle hooks, utilizing fragments, and improving performance. Let’s learn each of these aspects in detail.
The first major difference between Vue2 and Vue3 is creating an application from scratch.
You will have to follow the standard process, which includes installing Vue CLI(command-Line-Interface)
Also, in addition to differences in syntax, there are fundamental differences in the nature of the code itself. Creating an app involves a shift in how the code is written and the underlying principles guiding its development.
For example, in Vue2, when you use global configurations like mixins, it can cause issues during testing because the configurations can affect multiple instances, which leads to pollution of test cases.
Let’s look at an example of Vue2:
// this mixin affects both below instances Vue.mixin({ /* ... */ }); const app1 = new Vue({ el: "#app-1" }); const app2 = new Vue({ el: "#app-2" });
However, in Vue3, you can avoid this problem by using the “createApp(),” which allows you to create separate instances for your app. You can also use a local configuration like mixins that only affect a single model.
Let’s look at an example of the Vue3 code:
const app = createApp(App); // This configuration effect only 1 instance app.mixin(/* ... */); app.mount("#app");
This way, you can create multiple instances of your app with their configurations without worrying about them affecting each other.
You can only have one main parent element in Vue 2. In this case, the “div” element is a single root element of the component, and If there are multiple elements, they must be first wrapped inside a single parent element.
Example of Vue2 component:
On the contrary, a component can have multiple root templates in Vue3, so you can quickly return an array of elements without wrapping them in a single-parent element.
In the below case, “h1” and “p” are both root elements of the component.
Example of Vue3 component:
It is an addition to Vue 3 that establishes a flexible way to organize code. The critical difference between Vue2 and Vue3 is the Composition API and how they handle organization and component logic.
As you can see below, the component logic is separated into various parts, which makes it harder to understand and maintain
Example of Vue2:
export default { data () { return { count: 0 } }, computed: { doubleCount () { return this.count * 2 } }, methods: { increment () { this.count++ } }, watch: { count (newValue, oldValue) { // do something when count changes } }, mounted () { // do something when the component is mounted } }
The Comparision API in Vue3 allows developers to collocate code based on logical concerns in the ‘setup()’ function making the code easier to maintain and organize. In Vue3, these features can be used in conjunction with the ‘setup()’ function to build Vue3 components:
Example of Vue3:
import { ref, computed, watch } from 'vue' export default { setup () { const count = ref(0) const doubleCount = computed(() => count.value * 2) const increment = () => { count.value++ } watch(count, (newValue, oldValue) => { // do something when count changes }) return { count, doubleCount, increment } } }
The Vue3 demonstrates the use of the “ref() function to create a reactive variable which is smaller in comparison to the Vue 2 “data()” method.
The “computed()” function creates a computed property while the “watch()” is used to watch the changes. All these functions are imported from the “Vue” package making it easy to use.
In Vue3, an interesting feature enables you to render a component in a different location than where they are logically placed, even though it is not within the scope of the app.
< example-component > < teleport to ="#teleport-target "> < pop-up / > < / teleport> < / example -component> < div id="teleport-target" >< / div>
For instance, in the above code provided, the “pop-up” component is placed inside the “example component,” but it is rendered within the div with the id ”teleport-target.” This feature is particularly beneficial for displaying components in the various parts of the app, such as Pop-ups and modals.
Vue2 Lifecycle method had lifecycle hooks such as beforeCreate(), created(), beforeMount(), mounted(), beforeUpdate(), updated(), beforeDestroy().
Example of Vue2:
export default { data() { return { message: "Hello, world!", }; }, created() { console.log("Component created"); }, mounted() { console.log("Component mounted"); }, updated() { console.log("Component updated"); }, destroyed() { console.log("Component destroyed"); }, };
However, in Vue3, all life cycle hooks are within the setup() method, and some hooks are renamed. For instance,
beforeDestroy()
renamed beforeUnmount()
destroyed()
renamed unmounted()
.
Example in Vue3:
import { onBeforeMount, onMounted } from "vue"; export default { setup() { onBeforeMount(() => { console.log("Before mount"); }); onMounted(() => { console.log("Mounted"); }); }, }
Above is an example of how we can utilize onBeforeMount() and onMounted() within setup() to handle what we previously needed to do in beforeCreate() and created().
The Composition API replaces the old Options API and uses the setup() method as an equivalent of the old beforeCreate() method, with created() immediately following it. This simplifies component creation and eliminates the need for lengthy, unnecessary methods.
Vue 2 only allows a single root node for components, whereas Vue 3 supports multiple root nodes using fragments for more dynamic templates.
In Vue 2, data properties are automatically reactive, but in Vue 3, you can use the reactive function to create more fine-grained and complex reactive data structures.
This function creates a proxy object that tracks changes to its properties, giving you more control over reactivity. Overall, Vue 3 offers more flexibility and control over reactivity compared to Vue 2.
There are significant technical differences that we covered now, let us also have a look at the other improvements that one must consider to upgrade vue 2 to vue 3.
As we move to the migration tutorial following are the breaking changes that you should look into for migration.
The migration process can be quite complicated and hectic. So, to ease out the process we have used a basic demo application that fetches the users’ data from JSON Placeholder API and will build a simple UI to display it.
So, here’s what we will be covering in our tutorial.
Here we used Vue-2 to create our app.
Navigate to your project and run the application using these commands.
Your browser will show the default UI as shown below.
Vue2 package.json file.
Each Vue Component lives inside the .vue file. A Vue component consists of three parts.
1. < template > – Contains component’s HTML
2. < script > – All the JavaScript logic is written inside this tags
3. < style > – Component’s CSS is written inside this tags
Here we create two components:
App.vue is the parent of all components. It defines the template of our page.
In Home.vue component we have done the following things:
Here we will receive ‘getAllUsers’ and ‘isLoading’ props. Once the data is fetched we will use a table to display users’ data. v-for will loop over the getAllUsers array on ‘tbody’ element and display user data. We will also implement one of the features offered by Vue2, i.e., ‘filters.’ Here we will use the ‘SetEmail’ filter. It will return the user’s email with 1st letter small.
Loading...
Name Username Company Name {{user.name}} {{user.username}} {{user.email | setEmail}} {{user.company.name}}
import axios from 'axios' import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { users: [], isLoading: false }, mutations: { GET_USERS(state, users) { state.users = users } }, actions: { async fetchUsers({commit, state}){ state.isLoading = true; const res = await axios.get('https://jsonplaceholder.typicode.com/users') commit("GET_USERS", res.data) state.isLoading = false } }, getters: { getAllUsers(state){ return state.users } }, modules: { } }
Output
Hire Vuejs developers from us who can seamlessly migrate your project, ensuring zero downtime and a future-ready architecture.
Now that we have finished building a basic demo application with Vue.js 2, it’s time to move forward with the migration process. Before diving into the files, here is the fundamental workflow you should follow for a successful Vue 2 to Vue 3 migration.
Install vue-router@4 and vuex@4 and update them to the latest version as shown below.
Create a vue.config.js file to set up the compiler option to get migration build work.
Once the basic configuration is complete, start the development server. You may encounter some error messages at this stage. Let’s look at them in detail and resolve them one by one.
First, we will fix the main.js file for vue3. Below is the comparison.
// main.js
Now, open router file and use the below code for migration.
Now update store file.
The remaing code in the store file would be as it is.
We also need to update the package.json file. Use the below image where we have updated the dependencies.
Vue 3 came with a new feature called ‘compositionApi’, which is a replacement for ‘optionsApi’ However, you can also use optionsApi.
Here we use compositionApi.
In Vue 3, ‘filters’ has been removed. Instead of filters, we can use the ‘computed()’ property.
Loading...
Name Username Company Name {{user.name}} {{user.username}} {{user.email.toString().charAt(0).toLowerCase() + user.email.toString().slice(1)}} {{user.company.name}}
Testing in vue2 and vue3 with jest is similar, but there are some differences to keep in mind.
Here’s how you can set up unit testing with jest in vue2.
If you use Vue CLI to create your project, then you can use the plugin called cli-plugin-unit-jest to create and run Jest tests.
This plugin gives us all required dependencies (including jest), also creates a jest.config.js file, and generates a sample test suite.
After that, you can install the Vue Test Utils package using npm or yarn like below.
Manual Installation
Here the main task is to install Vue Test Utils and vue-jest using npm or yarn to process SFCs:
Then, Jest can generate vue-jest files from .vue files. Here’s how you can do it. You can add the below configuration in package.json or in a separate Jest config file:
{ "jest": { "moduleFileExtensions": [ "js", "json", // tell Jest to handle `*.vue` files "vue" ], "transform": { // process `*.vue` files with `vue-jest` ".*\\.(vue)$": "vue-jest" } } }
For more details related to testing, you can check the below link.
installation
Create a new Vue3 project using vue-cli.
Here you have multiple options, but you can select the “Manually select features” option and take “Unit Testing” and “Jest” from the list of features.
Run below command to generate a sample test file.
Open the generated test file in the “tests/unit” folder and write your test code.
Run tests by running the following command.
Note that in Vue3, jest is configured to use the new “@vue/test-utils” package for testing components. This package provides utilities for mounting and testing Vue components in a Jest environment.
Migrating from Vue Test Utils v1
If you want to know the unit testing changes from vue2 to vue3 refer to the below link.
migration
So, these were the steps to implement the migration process to upgrade Vue 2 to Vue 3. You can visit the source code: vue2-to-vue3-example. Clone the repository and experiment with the code.
We hope this tutorial helps you get started with migrating from Vue 2 to Vue 3. Upgrading an enterprise-level or large-scale project can demand significant time, planning, and effort. However, by breaking the process into smaller, manageable modules, you can approach the migration more effectively.
If you need expert assistance, partnering with a Vue.js development company can ensure a smooth and well-structured transition tailored to your project’s specific needs.
No, you can incrementally migrate your application by leveraging the Vue 3 migration build. During the transition, it allows backward compatibility for most Vue 2 features.
It’s optional but recommended. It helps better organize logic, especially in large apps, and improves code reusability. You can adopt it gradually alongside the Options API.
Vue Router v4 is required for Vue 3 and includes a new setup with different syntax and TypeScript support.
Your Success Is Guaranteed !
We accelerate the release of digital product and guaranteed their success
We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.