Javascript is required
1 min read

Vue Tip: When You Should Use a Composable

Vue Tip: When You Should Use a Composable Image

Vue Composables are a way to encapsulate logic in a reusable way and they are one of my favorite features of Vue 3.

They are a great way to share logic between components, but I often see them used in places where they are not needed. In this short tip, I will explain when you should use a composable and when you should not.

Let's take a look at the following code example:

1export const useDate = (dateString: string) => {
2  const date = new Date(dateString)
4  const getFormattedDate = () => {
5    return date.toLocaleDateString()
6  }
8  return {
9    date,
10    getFormattedDate
11  }

What do you think, would you call this method a composable or not?

The answer is: No.

Let's take a look at the official documentation:

In the context of Vue applications, a "composable" is a function that leverages Vue's Composition API to encapsulate and reuse stateful logic.

The key part here is stateful logic which involves "managing state that changes over time". In our example, we are not using any reactive state, so this is not a composable. I would call it a utility/helper function.

Let's define a simple rule of thumb:

Rule of thumb for composable functions

If your function does not manage any reactive state, doesn't register any lifecycle hooks or doesn't provide/inject anything, it is not a composable.

Finally, let's take a look at a good example of a composable:

1import { ref, onMounted, onUnmounted } from 'vue'
3export const useMouse = () => {
4  const x = ref(0)
5  const y = ref(0)
7  const update = (event) => {
8    x.value = event.pageX
9    y.value = event.pageY
10  }
12  onMounted(() => window.addEventListener('mousemove', update))
13  onUnmounted(() => window.removeEventListener('mousemove', update))
15  return { x, y }

This composable manages the mouse position and provides two reactive values x and y. It also registers and unregisters an event listener when the component is mounted and unmounted.

If you liked this Vue tip, follow me on X to get notified about new tips, blog posts, and more. Alternatively (or additionally), you can subscribe to my weekly Vue & Nuxt newsletter:

I will never share any of your personal data. You can unsubscribe at any time.