Vuejs composables: hands-on examples

Hssan Bouzlima - Aug 15 '23 - - Dev Community

Composition API'S was introduced in vue from 2.7 version to replace options API'S.

On of These API's is Reactivity api ('ref' and 'reactive') to declare reactive state, instead of data function in option API.

This new API is the backbone of composables.


What are composables?

Composables are functions based on reactivity api following a specific structure making it possible for developers to separate stateful or stateless logic from components.

In addition, logic itself could be split in different composables and nested together to achieve a specific task on account of the fact that composables are 'malleable' through arguments.


Composables examples:

Composable have three major parts:

Internal state: Any state related to the function.
States that will be exposed must be reactive using 'ref' or 'reactive'.

Nevertheless, it is recommended to use 'ref' since it retains reactivity and enables destructuring in components straightforward compared to 'reactive'.

Manage state: A logic to apply when an action happens

Return state: Expose managed state

Composable returns an object with single value or multiple values, a value could be a method.

1. Basic composable

In the example below useIsUserActive is a composable to check if a user click somewhere in the page.


Basic composable example: useIsUserActive

composable example1

Then imported and executed in vue component.


Basic composable example: useIsUserActive called in component

composable example1-template
You may notice that composable name starts with use as it is the naming convention from vuejs team.

2.Composable with returned methods:

Let's see more sophisticated example: useTimer

This composable will act as a timer that we can control through different methods: start, pause and stop.

useTimer example

composable example2

useTimer composable called in component

composable example2-template

3.Composable with arguments:

Composable could be parametrized as the example below.

This composable is responsible for replacing spaces in strings with specific separator.


useFormatString example

composable example3

useFormatString called in component

composable example3-template

  • data and separator are the parameters.

  • watchEffect will be run whenever one of its dependencies change. Without watchEffect our function will run only the first time even though data or separator have been changed.
    Its dependencies must be reactive to be capable of doing this job, for that reason data and separator must be a ref.

  • toValue is a function that returns either:

     1.Normalized value of the source if that source is a ref.

     2.Execute the function of the source and returns its value if
that source is a getter function.

     3.Returns value of the source if that source is a normalized
value.


Composables advantages:

Let's use useTimer composable logic straight inside the component.



<script setup lang="ts">
import { ref } from "vue"

const timer = ref(0)
let myInterval: number

// start method
const start = () => {
  myInterval = setInterval(() => {
    timer.value = timer.value + 1
  }, 1000)
}

// pause method
const pause = () => {
  clearInterval(myInterval)
}

// stop method
const stop = () => {
  timer.value = 0
  clearInterval(myInterval)
}
</script>

<template>
  <main>
    {{ timer }}

    <button @click="start()">start</button>
    <button @click="pause()">pause</button>
    <button @click="stop()">stop</button>
  </main>
</template>


Enter fullscreen mode Exit fullscreen mode
  • You will notice that the component does not care of timer state, then it does not make any sense for the component to have access to timer logic.

  • You will not be capable of reuse this logic unless you copy paste.

  • Imagine this component get bigger, it will be more difficult to debug.

As you may notice this technique will offer lighter components regarding components complexity and length. Besides easier debugging.


Conclusion:

Composables are the new way of reuse and encapsulate logic in vuejs application. They gain this power from composition api the thing that take vuejs application to another level.

Implementing composables, from personal use in several projects, won't cost neither ambiguity nor new layer of complexity compared to their advantages.

You find the examples above in my github: Github

. . . . . . . . . . . .