Breaking changes in Vue 3, How to migrate from Vue 2 App to Vue 3?

Harish Kumar · · 2818 Views

The Vue.js 3 core has formally released on 18 September 2020 🎉 🥳. It means the Vue 3 core is now stable. But there's a phased release process that will be finished before the end of 2020 when other official frameworks sub-projects will reach to stable status.

Here are the Vue 3 docs, alongside a migration guide that includes what has changed.

The Vue 3 code base is highly compatible with Vue 2. So, you shouldn't need to change the code to move to the new version. Or, you didn't need to re-learn everything from scratch. But instead, opt into new features.

In this article, I'll walk you through the relevant breaking changes and new features. So, let’s dive in:

Migration to Vue 3

Before start migrating, first you should read the official migration guide. And modify the application code base according to the breaking changes. In the below video, you can see how can migrate your existing Vue 2 app to Vue 3.

Vue app initialization

The first thing that you will experience is the distinction in initializing the Vue app. In Vue 2, you need to utilize Vue constructor with a render function and the $mount method like this:

import Vue from 'vue'
import App from './app.vue'

const app = new Vue({
  render: (h) => h(App),
}).$mount('#app')

In Vue 3, that simplified with a more elegant syntax structure.

import { createApp } from "vue";
import App from "./App.vue";
createApp(App).mount("#app");

Event Bus is deprecated

Do you love the idea of the Event Bus in Vue?

If yes, this may disappoint you. Vue has officially removed $on, $off and $once methods from the instance completely. Vue instances no longer implement the event emitter interface. That means you cannot implement the Event bus in vue3.

// Vue 2 example of event bus

const eventBus = new Vue();

// subscribe
eventBus.$on('event-name', () => console.log('event-name!'));

// publish
eventBus.$emit('event-name');

If you want to use the Event Bus pattern in your application, then you can use an external library implementing the event emitter interface, for example, mitt or tiny-emitter.

Filters is deprecated

In 2.x, developers could utilize filters so as to apply basic content formatting.

For example:

<template>
  <p>{{ price | currencyUSD }}</p>
</template>

<script>
  export default {
    data() {
        return {
            price: ""
        }
    },
    filters: {
      currencyUSD(value) {
        return '$' + value
      }
    }
  }
</script>

In 3.x, filters are eliminated and not at this point supported. Instead, suggested using method calls or computed properties.

<template>
  <p>{{ priceInUSD }}</p>
</template>

<script>
  export default {
    data() {
        return {
            price: ""
        }
    },
    computed: {
      priceInUSD() {
        return '$' + this.price
      }
    }
  }
</script>

Composition API

One of the most noteworthy changes is that new API that will allow for a function-based way of writing your component, inspired by React Hooks.

Vue 3 will still support Options API, so if you don't want to use composition API, you can always use the traditional methods used in Vue 2.

Example of Composition API:

<template>
  <button @click="increment">
    Count is: {{ state.count }}, double is: {{ state.double }}
  </button>
</template>

<script>
import { reactive, computed } from 'vue'

export default {
  setup() {
    const state = reactive({
      count: 0,
      double: computed(() => state.count * 2)
    })

    function increment() {
      state.count++
    }

    return {
      state,
      increment
    }
  }
}
</script>

Fragments (Multiple root elements in template)

In Vue 2, multi-root components were not supported. The solution was to enclose your code in a wrapper element.

// in Vue 2
<template>
  <div>
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  </div>
</template>

In Vue 3, now components can have multiple root nodes. That allows us to remove wrapper elements and composing cleaner markup.

// in Vue 3
<template>
  <header>...</header>
  <main>...</main>
  <footer>...</footer>
</template>

Teleport

A not all that common issue, however exceptionally hard to comprehend is having part of your segment mounted in a different position in DOM than the Vue component hierarchy.

A typical scenario for this is making a full-screen modal component. In most cases, you'd need the modal's logic to live inside the component. However, the positioning of the modal gets hard to solve through CSS, or requires an adjustment in component creation. This can now effortlessly accomplished with the utilization of the teleport feature.

Example:

app.component('app-modal', {
  template: `
    <button @click="isOpen = true">
        Open modal
    </button>
    <teleport to="body">
      <div v-if="isOpen" class="modal">
          I'm a teleported modal
      </div>
    </teleport>
  `,
  data() {
    return { 
      isOpen: false
    }
  }
})

You can still interact and pass props to it like being inside the component!

0

Please login or create new account to add your comment.

0 comments
You may also like:

A Beginner’s Guide to Efficient Memory Use in JavaScript

Managing memory efficiently in JavaScript applications is essential for smooth performance, especially for large-scale or complex applications. Poor memory handling can lead to (...)
Harish Kumar

Understanding the `.reduce()` Method in JavaScript

The .reduce() method in JavaScript is one of the most powerful array methods used for iterating over array elements and accumulating a single value from them. Whether you're summing (...)
Harish Kumar

Building a Real-Time Chat App with Laravel Reverb and Nuxt 3

Building a real-time chat application is a great way to understand the power of WebSockets and real-time communication. In this tutorial, we will walk through creating a Real-Time (...)
Harish Kumar

How to Use JavaScript’s .every() and .some() for Smarter Array Handling

JavaScript provides a variety of array methods that allow developers to perform common tasks in an efficient, clean, and readable manner. Among these methods are .every() and .some(), (...)
Harish Kumar

How to Set Up Nuxt 3 Authentication with Laravel Sanctum (Step-by-Step Guide)

In modern web development, securing your application’s authentication process is a top priority. For developers building Single Page Applications (SPA) or Server-Side Rendered (...)
Harish Kumar

Understanding `.slice()` and `.splice()`: JavaScript Array Methods

In JavaScript, arrays come with numerous built-in methods for manipulation. Two commonly used methods are .slice() and .splice(). While they sound similar, their purposes and behaviors (...)
Harish Kumar