When the Vue3 'request for change' came out, one major change was accounted. A new API for writing the logic and handling the lifecycle of your Vue applications, called the composition API. It greatly differed from the familiar Options API that so many grew to love. This started a bit of a controversy which led to the Vue Team leaving support for the Options API in Vue3. They of course moved forward with composition but made it optional.
This leads to both being fully supported and a great experience for people migrating from Vue 2 to Vue 3, allowing for gradual component to component refactoring.
Benefits of composition API vs options API
- Keep functionality blocks together
- Better performance
- Easier to extract and import logic
- Cleaner code
For more indepth information on composition API read through the Vue.js Docs
Here's an example migration from Options API to Composition API
First lets take a look at the component we'll be converting
Options API:
<template>
<div id="app">
<h2>{{date}}</h2>
<p>I drank {{cupsOfWater}} cups of water today 🥤</p>
<button @click="drinkCup">Drink a cup</button>
<p v-if='cupsOfWater > 0'>I drank the last cup at {{lastCup}}</p>
</div>
</template>
<script>
export default {
data() {
return {
cupsOfWater: 0,
date: '',
lastCup: ''
};
},
methods: {
drinkCup() {
this.cupsOfWater++
}
},
watch: {
cupsOfWater: function (val) {
this.lastCup = new Date().toTimeString()
}
},
mounted(){
this.date = new Date().toDateString()
}
};
</script>
This is just a simple app which allows you to track how many cups of water you drink a day
The lifecycle hooks are clearly seen here, and completely separated out. Leaving you to reason out what functionality and variables go together. Although in a small app this is fairly easy to see, in a larger codebase, it can get quite complicated.
To start the migration from Options to Composition we add the setup function, which is the only hook required in the composition API.
setup(){
}
Then lets move the cupsOfWater
declaration and drinkCup()
incrementing function to setup()
import {ref} from 'vue'
setup(){
const cupsOfWater = ref(0)
function drinkCup(){
cupsOfWater.value++
}
return {
cupsOfWater,
drinkCup
}
}
Lets break down what we just did
- imported the
ref
functionality to show that a variable is meant to be reactive - declared
cupsOfWater
as a reactive variable with a initial value of 0 - created a new function called
drinkCup()
which increments our reactivecupsOfWater
variable, .value is required to access and change the value of reactive variables - returned
cupsOfwater
anddrinkCup
so that it is accessible in the template (html)
We've still got a few more pieces of logic to move over to the setup()
hook. Lets take a look at how it will look once it's fully migrated
<template>
<div id="app">
<h2>{{date}}</h2>
<p>I've drank {{cupsOfWater}} cups of water today 🥤</p>
<button @click="drinkCup">I drank a cup</button>
<p v-if='cupsOfWater > 0'>I drank the last cup at {{lastCup}}</p>
</div>
</template>
<script>
import {ref, onMounted, watch} from 'vue'
export default {
setup(){
const cupsOfWater = ref(0)
function drinkCup(){
cupsOfWater.value++
}
const lastCup = ref('')
watch(cupsOfWater, ()=>{
lastCup.value = new Date().toTimeString()
})
let date = ref('')
onMounted(()=>{
date.value = new Date().toDateString()
})
return {
date,
cupsOfWater,
drinkCup,
lastCup
}
}
};
</script>
The logic in the above codeblock is clearly separated into functional blocks. We immediately can tell which variables belong to which piece of functionality.
Give it a try in your own projects! Vue2 now has a plugin composition-api that you can install. This will give you a good idea of how your future migration will go and might make it easier for you to adapt when the time comes to fully migrate.
The Goal
With this article I wanted to provide another side by side example of Options to Composition API migration. When I was looking through the documentation I didn't find enough of these. Let me know if you want me to create more!
Check out HTML All The Things
HTML All The Things is a web development podcast and discord community which was started by Matt and Mike, developers based in Ontario, Canada.
The podcast speaks to web development topics as well as running a small business, self employment and time management. You can join them for both their successes and their struggles as they try to manage expanding their Web Development business without stretching themselves too thin.
Our latest episode takes the bold stance that Vue is Better Than React
Top comments (5)
Hi, thanks for the article, just what I've been looking for. So if I have an api request in a method, then I define the result variables, and then in a function call the api?
I don't think you need
this.content = response
Just
content = response
Hi, content (without this) doesn't pick up the value of response. Do you know why? Thanks.
Ignore me, need to add . value...
content.value = response.data. ...
yeah sorry! I forgot, haven't used vue3 in a couple months.
Totally right though. .value to get the value. Thanks for updating!