Learning the Composition API

Learning the Composition API

This past month, I visited the local Hack & Tell to write a web app that uses Vue.js‘s Composition API. I have written 41 posts involving Vue on this blog but the Composition API is new here.  If you are the “eat your dessert first” type, you can check out the result at https://joes-job-tracker.web.app.  I want to spend this article reviewing the composition API, though.

Let me start by explaining what the Composition API is.  The Composition API is a collection of APIs that enable the creation of Vue components by utilizing imported functions, as opposed to the traditional method of declaring options. This term encompasses the Reactivity API, Lifecycle Hooks, and Dependency Injection. The Composition API is an integrated feature within both Vue 3 and Vue 2.7.  It is a bit of a departure from the traditional Vue 2 way of writing code but Vue 2 applications can use the officially maintained @vue/composition-api plugin.

So, what do the differences actually look like?  Let’s take a look at the example of an app that tracks the location of the user’s mouse cursor.  The first version uses the Vue 2 method where you declare options and the second version does the same thing but uses imported functions.

See the Pen
Track Mouse - Vue 2
by Joe Steinbring (@steinbring)
on CodePen.

See the Pen
Track Mouse - Composition API
by Joe Steinbring (@steinbring)
on CodePen.

 

So, what are the differences between the two?  Let’s compare and contrast.

Vue 2Composition API
new Vue({
el: '#app',
data: {
mouseX: 0,
mouseY: 0,
},
methods: {
trackMouse(event) {
this.mouseX = event.clientX;
this.mouseY = event.clientY;
},
},
mounted() {
// Attach an event listener to track mouse movement
window.addEventListener('mousemove', this.trackMouse);
},
beforeDestroy() {
// Clean up the event listener to prevent memory leaks
window.removeEventListener('mousemove', this.trackMouse);
},
});
import { createApp, ref, onMounted, onBeforeUnmount } from 'vue'

createApp({
setup() {
const mouseX = ref(0);
const mouseY = ref(0);

const trackMouse = (event) => {
mouseX.value = event.clientX;
mouseY.value = event.clientY;
};

onMounted(() => {
window.addEventListener('mousemove', trackMouse);
});

onBeforeUnmount(() => {
window.removeEventListener('mousemove', trackMouse);
});

return {
mouseX,
mouseY,
};
},
}).mount('#app')

In the Vue 3 Composition API version, the setup function is used to defines the component’s logic, and it uses reactive references (ref) to manage the state.  Event handling is encapsulated within the onMounted and onBeforeUnmount lifecycle hooks.  Vue 3 promotes a more modular and declarative approach.  In the Vue 2 version, the code uses the Options API with a more traditional structure, relying on data, methods, and lifecycle hooks like mounted and beforeDestroy.  Vue 3’s Composition API simplifies the code structure and encourages better organization and reusability of logic.

If you are anything like me, your first question is what reactive references are.  Vue 2 doesn’t have a built-in equivalent to the ref and reactive features found in Vue 3. When you use a ref in a template, modifying its value triggers Vue’s automatic detection of the change, leading to a corresponding update of the DOM.  This is made possible with a dependency-tracking based reactivity system. During the initial rendering of a component, Vue meticulously monitors and records every ref used in the process. Subsequently, when a ref undergoes a mutation, it initiates a re-render for the components that are observing it.

Here are the Vue 2 and the Composition API versions of the same application:

See the Pen
Vue 2 Equivelent to composition API Ref
by Joe Steinbring (@steinbring)
on CodePen.

See the Pen
Track Mouse - Composition API
by Joe Steinbring (@steinbring)
on CodePen.

Vue 3’s reactivity system is more efficient and performs better than Vue 2.  This can result in better overall performance, especially in applications with complex reactivity requirements.  It also reduces the use of magic keywords like this, which can be a source of confusion in Vue 2.

 

Here are the two versions, side by side:

VUE 2COMPOSITION API
new Vue({
el: ‘#app’,
data: {
myValue: 42,
},
methods: {
updateMyValue() {
this.myValue = 69; // Update the value
},
},
});
import { createApp, ref, onMounted } from ‘vue’;

const app = createApp({
setup() {
const myValue = ref(42);

const updateMyValue = () => {
myValue.value = 69; // Update the value
};

return { myValue, updateMyValue };
}
});

app.mount(‘#app’);

 

Another thing that the Composition API brings to the table is composables. Vue composables are special functions that leverage the Composition API to create reactive and reusable logic. They serve as external functions, abstracting reactive states and functionalities for use in multiple components. These composables, also known as composition functions, streamline the process of sharing logic across different parts of an application.

In functionality, composables are akin to Vue 2’s mixins found in the Options API and resemble the concept of Hooks in React.

I am going to wait for a future post to cover composables, though.

Leave a Reply

Your email address will not be published.