Easily switch to Composition API in Vue.js 3
The fact that Vue.js 3 already reached the alpha version made me think that... it's time already for some Vue.js 3 tips!
The idea is to give you some tips related to new features you can find on Vue.js 3 as they get available. For now, we'll focus on Composition API, one of the most game-changing features!
This first one is specially focused on showing you a basic step-by-step guide or cheatsheet to migrate object-api Vue.js components to use Composition API. In future tips you'll also see how to apply certain new techniques this API allow us to do as well 😉.
I'll do that by showing you how to convert an Object-API-based component to use Composition API.
For that, let's create a MoneyCounter.vue component that basically shows a money amount and allow us to add/substract quantities to it, implemented using the following code:
<template>
<div>
<h2>{{ formattedMoney }}</h2>
<input v-model="delta" type="number">
<button @click="add">Add</button>
</div>
</template>
<script>
export default {
data: () => ({
money: 10,
delta: 1
}),
computed: {
formattedMoney() {
return this.money.toFixed(2);
}
},
mounted() {
console.log("Clock Object mounted!");
},
methods: {
add() {
this.money += Number(this.delta);
}
},
watch: {
money(newVal, oldVal) {
console.log("Money changed", newVal, oldVal);
}
}
};
</script>
This component has a money
state which holds the quantity, the delta
that is bound using v-model
to the input and later used in the add
method to add that quantity to money. The computed property formattedMoney
correctly displays the decimal values of money
. Finally, I also included a dummy watch
and mounted
with a console.log
statement for the purpose of showing how to migrate it to Composition API.
Take some time to understand this component if you need it.
Right away, create a MoneyCounterComposition.vue component. This component shares the same <template>
than the previous, since template is not affected by API's, so copy it from the previous component.
The change is in the <script>
part. Let's check first how it'd be all code:
// In Vue 3, you'll import from "vue"
import { ref, computed, watch, onMounted } from "@vue/composition-api";
export default {
setup() {
// State
const money = ref(10);
const delta = ref(1);
// Computed props
const formattedMoney = computed(() => money.value.toFixed(2));
// Hooks
onMounted(() => console.log("Clock Object mounted"));
// Methods
const add = () => (money.value += Number(delta.value));
// Watchers
const moneyWatch = watch(money, (newVal, oldVal) =>
console.log("Money changed", newVal, oldVal)
);
return {
delta,
money,
formattedMoney,
add,
moneyWatch
};
}
};
First of all, we're exporting an object with the setup
function. This is required and here's where all happens. Now let's focus part by part:
State: it's implemented using ref
, and as you can see you can have as many as you want. To access them you don't need to access "this
", since it's just a variable not a "magic" instance thing (yay!), although to change its value you need to access the .value
property. You could use reactive
as well, but I encourage use to read this article from Jason Yu and use ref
as a convention.
Computed: you need to use computed
for it. It's basic: it takes a function as its first argument.
Hooks: every hook has its own utility. In the case of mounted
hook its onMounted
. Same shape as computed
: they take a function as their first argument.
Methods: they're just functions, like any other. Nothing special here.
Watch: there are different signatures. That's the one equivalent to watch money
, but you can check all shapes in the RFC docs.
Finally, the setup
function must return an object containing everything you want to use in the template. Anything that is not there, it won't be accesible from the template.
A little note: you may notice that I'm importing from "@vue/composition-api". That's because I'm using a plugin since Vue 3 is not there yet, but with the plugin we can already use it.
I hope the following image helps you understand how to migrate this component by this side-by-side perspective:
If you want to see with your own eyes that this code truly works, go and check it in this CodeSandbox!
That's it for today's tip!
Related Articles
The new Provide and Inject in Vue 3
Getting stuck into the prop drilling? Learn how provide/inject can make your components more flexible and independent in this short tutorial.
Jul 18, 2022
The 101 guide to Script Setup in Vue 3
Don't you know about Script Setup yet? Check out this short article now and learn the nicest way to define a Vue component right now!
Jun 20, 2022
Going 3D with Trois.js and Vue 3
Learn about Trois.js, a JS library to render 3D scenes in Vue. In this article, we're learning the basics of using Trois.js in a Vite + Vue 3 app
Nov 16, 2021
Sponsors
VueDose is proudly supported by its sponsors. If you enjoy it, consider supporting it to ensure the project maintainability.