Both composables and components are very fundamental to creating any Vue application. However, both are very different concepts and can be used alongside each other.
Components are the building blocks of a Vue application. Each component encapsulates both rendering and working logic in an instance. In addition, components can have child components that inherit data and traits from parent components.
Composables are functions that a user can create using the Composition API and share for use within different components. Their primary use is to make a piece of code reusable, especially if it is stateful logic.
Through composables, users can take a component's logic and make a function out of it that can be used by other components, even if they don't necessarily have the same kind of state. Additionally, you can create a composable function out of other composables to just simplify the logic.
As an example, check the following code that uses the Composable API for mouse tracking.
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const x = ref(0)
const y = ref(0)
function update(event) {
x.value = event.pageX
y.value = event.pageY
}
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
</script>
<template>Mouse position is at: {{ x }}, {{ y }}</template>
We can divide this code and create composables out of this code for use among different components in the following way.
import { ref, onMounted, onUnmounted } from 'vue'
function eventListener(target, event, callback) {
onMounted(() => target.addEventListener(event, callback))
onUnmounted(() => target.removeEventListener(event, callback))
}
export function trackMouseLocation() {
const x = ref(0)
const y = ref(0)
eventListener(window, 'mousemove', (event) => {
x.value = event.pageX
y.value = event.pageY
})
return { x, y }
}
Now, if we wish to use this composable in a component, we can do so in the following manner.
<script setup>
import { trackMouseLocation } from './mouse.js'
const { x, y } = trackMouseLocation()
</script>
<template>Mouse location is: {{ x }}, {{ y }}</template>
Note: Commonly asked Vue.js interview question