Vue Composable
Vue3 introduced vue-composable, and it is one of the most useful features of Composition API. It is an extended version of vue Mixin but it’s better than that. Let’s deep dive into it.
WHAT IS VUE COMPOSABLE?
Vue composable are functions that use composition API to implement reusable and stateful logic now what do we mean by stateful reusable logic? we are habitual to write utils, or common service typescript files to extract common logic. but the problem with these functions is they are not reactive, if we want to update the UI/state based on new updated variable values then it becomes messy/difficult to do with this function. Vue Composables are here to solve this problem! It is very useful to increase the reusability of common functionality. Compostables are external functions and that can be used in any number of components.
SIMPLE CODE EXAMPLE OF VUE COMPOSABLE
Let’s understand composable with a simple code example — with a simple countdown timer
// countDown.js
import { ref, onUnmounted } from "vue";
export function useCountDown(countdownDuration) {
const remainingTime = ref(countdownDuration);
const timer = setInterval(() => {
if(remainingTime.value <= 0) {
clearInterval(timer);
}
remainingTime.value = remainingTime.value - 1;
}, 1000);
onUnmounted(() => {
return () => {
clearInterval(timer);
};
});
return {
time: remainingTime,
};
}
// compA.vue
<template>
<h1>Hello from component - B: {{time}}</h1>
</template>
<script setup>
import {useTimer} from "../composables/timer.ts"
const {time} = useTimer(100)
</script>
Here, the compA will show a countdown starting from 100 till 0, you can create a similar compB and can pass different stating values — let’s say from 200 then it will show count down starting from 200 till 0
yey! So we have 2 different components using the same composable countdown file.
VUE COMPOSABLE EXPLAINED EVERYTHING
The vue composable makes your codebase more reusable, offering a simpler, more flexible, and more efficient.
The number of times the instance is called will create a new copy of stateful variables, for an example if in the above code countDown.ts has a stateful-reactive variable say remainingTime and it is imported in 2 different components say compA and compB then all the components will create a different copy of the variable remainingTime
this will not interfere the each other’s state. If you want to have a shared state use Vuex store — store management.
ADVANTAGES OF USING VUE COMPOSABLE
- Reusability: Composable functions extract logic functionality from common features enabling you to reuser in multiple components without
- any code duplication Readability: code becomes more readable for anyone to debug or do any further development
- Reactive state: Composable are very useful as they are stateful, variables defined inside are reactive can can update ui based on it.
VUE COMPOSABLE VS. MIXINS
Yeah, so the kind of similar thing can be achieved by mixins as well, then why vue-composable? here is the list of reasons why Composable is better than Mixin
- Less code readability with the source of properties: when many mixins are imported, the source of properties becomes unclear, leaving your code less readable.
- Coupling between multiple Mixins: if multiple mixins need to be communicated with each other then it needs to be done vis shared properties only, which makes it implicitly coupled, on other side with composable return value from one composable can be passed to another composable as an argument just like a normal function
PERFORMANCE REVIEW
While this is a very good setup for reusable code, be careful as well while using it. for example, if have some event listeners attached in the logic, and using this method you end up with event listeners being attached for each component, meaning if there are 100 components using useYourMethod you’ll have 100 event listeners attached to the body, each performing the update function which, when added up with other compostables, can soon become a performance bottleneck. some code like this…
onMounted(() => {
console.log('mouse event listener bound')
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
window.removeEventListener('mousemove', update)
})
So the way you are using the composable decides the impact of it on the performance. If you want to use its function on 100 components at the same time, on the same page then a singleton would be a good option. But if you want to use the composable in many pages that are separated by the vue router, the composable can be a good option to use also, remember to clean the side effects in onUmMounted — something like removeEventListener
Happy reading!