Vue2 to Vue3 — What’s changed?

Thilanka Dilakshi
Embla Tech
Published in
5 min readJul 4, 2021

This article gives a brief introduction to some of the new changes added in Vue3 compared to Vue2.

Vue 3?

Vue 2 has been around for quite some time and has the reputation for being simple, user friendly and light among many other benefits. Vue3 was officially release in 2020 and said to be faster, smaller, more maintainable and easier to target native compared to Vue2. Vue3 is more or less a rewritten version of Vue2 and comes with some new and significant changes and features. However, basic syntax of Vue2 and Vue3 are very similar.

In Vue2, as the code grows components become less readable and hard to maintain. The most important addition in Vue3 is Composition API, which is introduced to solve this problem. With Composition API, the component code can be organized based to logical concerns, as opposed to Vue2’s distributed code segments in multiple components options based on Options API.

Apart from this major features, there are several new changes added in Vue3 to make a developer’s life easier.

New changes in Vue3

Following are some major new changes introduced in Vue3 which will be discussed in this article.

  1. Composition API
  2. Changes in Vue life cycle
  3. Teleport
  4. Fragments
  5. Initialization code

Composition API

One of the advantages of using Vue is the ability to extract repeatable parts of the code along with its functionality. Even though this plays a huge role in improving maintainability and flexibility of the code, it might become harder when the application grows with many components.

In Vue2, component’s options such as data, computed, methods, watch are used to organize the logic. This approach makes it hard to read and understand the code in case of a grown component.

Here’s an example of a basic Vue2 code.

export default {
components: { Component1, Component2 },
props: {
prop1: {
type: String,
required: true
}
},
data () {
return {
object 1,
object 2
}
},
watch: {
prop1: 'method1' // 1
},
methods: {
method1() {
// implementation
},
mounted () {
// implementation
}
}

Regardless of the logic, various code segments are scattered among several component options. This separation makes it hard to read and understand the code based on a logical point of view as the reader has to move around the code.

Composition API gives a solution by allowing us to collocate code based on logical concerns.

setup()option is used to return the properties to the rest of the components.

import { Component1} from '...'

// inside our component
setup (props) {
let object1 = ''
const method1 = () => {
// implementation
}

return {
object1,
method1 // functions returned behave the same as methods
}
}

Other parts of the code can access the returned content. Inside setup, we can group code segments by logical concerns since we can have lifecycle methods, computed properties, state data, etc.

Changes in Vue life cycle

Life cycles hooks function similarly in Vue2 and Vue3 but with Composition API, accessing to these life cycle hooks have changed as follows.

beforeCreate and created lifecycle hooks are not needed since setup() is replacing them and performing the exact functionality. And it is important that these life cycle hooks are imported before using them.

For example, onBeforeMount will be written as,

import { onBeforeMount } from 'vue'
export default {
setup() {
// mounted
onBeforeMount(() => {
// implementation
})
}
}

In other words, every life cycle hook and it’s content should be inside setup().

Teleport

Teleport gives the ability to render a component in a different location that where it’s placed logically, even if it’s not in the app’s scope. This comes in handy specially when using popups and modals.

<example-component>
<teleport to="#teleport-target">
<pop-up />
</teleport>
</example-component>
<div id="teleport-target"></div>

Simply, even though pop-up is positioned inside example-component, it is rendered within the div with id teleport-target. Of course this can be done with some css magic, but Vue3 has made it easier.

Fragments

In Vue2, it is impossible to use multiple root elements within a template. This would result in errors and to fix this, typically a div is used.

<template>
<div>
<header>...</header>
<main>...</main>
<footer>...</footer>
</div>
</template>

In Vue3, it is possible to declare multiple roots in a template without any issues using Fragments API, which helps in a cleaner code without having to use unnecessary wrappers. However, it is required to explicitly define where attributes should be distributed.

<template>
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>
</template>

Initialization code

In Vue3 createApp method is introduced to initialize the app. This method returns a new instance of a Vue app. Each instance can have it’s own functionalities without affecting the other instances.

const app1 = createApp({})
const app2 = createApp({})
app1.directive('focus', {
inserted: el => el.focus()
})
app2.mixin({
/* ... */
})

Although it is not common to create multiple apps in the same application, this might come in handy when the project grows in size. With Vue3 it is possible to configure each app as an independent object. It is also possible to share some functionalities among several instances.

Summary

Even though not much has changed from Vue2 to Vue3, some changes with improve the maintainability, readability and speed has been added with some syntax changes. This article contains few of the major changes introduced.

--

--

Thilanka Dilakshi
Embla Tech

Web developer | Coding enthusiast | Knowledge seeker