Abiola Farounbi Frontend developer and technical writer with a passion for open source, accessibility, and web technologies.

Getting started with Vue composables

5 min read 1571

Deep Dive Vue Composables

Vue 3 introduced several new concepts and different ways of handling logic, one of which is Vue composables. Vue composables allow us to extract reactive state and functionality to reuse in other components.

In this article, we‘ll gain a comprehensive understanding of Vue composables by implementing them in a Vue application. Let’s get started!

What are Vue composables?

Vue composables are functions that use the composition API to implement a reactive and reusable logic. Composables act as an external function that extracts reactive state and functionality to be used across several other components. Composables can alternatively be called composition functions.

Composables are similar to mixins in the Options API In Vue 2, as well as the implementation of Hooks in React.

Reusability of composable functions

In modern web applications, the codebase is always divided into different components, providing an organized structure and easy workflow. With composable functions, you can further simplify your workflow by extracting and importing functionality into an external file that can then be used in multiple components.

The concept behind composable functions is brought about by the Composition API, which gives you the full flexibility to organize your component code into smaller functions based on logical concerns.

The reusable features of a composable function offer many benefits. For one, the extracted logic can be reused, promoting code organization with a structure that is easy to navigate. Composables can also serve as a utility function that uses a reactive state and can be customized for different purposes in an application.

Finally, composables can manage the state of the output depending on the use case, allowing you to choose whether the state should be global or local. This freedom eliminates some of the complexity and dependencies in comparison to other state management tools.

Another interesting thing about composables is that they can be nested within each other, meaning one composable function can call one or more other composable functions. Therefore, we are able to break down complex logic into smaller units, like how we separate an entire application using components.

Creating a Vue composable from scratch

Let’s try it out by creating and using composables in a Vue application. To follow along with this tutorial, you’ll need Node.js and the Vue CLI installed. First, create the Vue project as follows:

We made a custom demo for .
No really. Click here to check it out.

vue create vue-composables

Once the project has been created, navigate into vue-composables with the following code:

cd vue-composables

For an organized structure, we’ll create a separate folder to handle all the composables needed for the project.

Using the Web Speech API, we’ll create a custom composable that is used for speech recognition. The Web Speech API enables developers to implement speech recognition and speech synthesis features in the web browser, giving web apps the ability to convert voice data into readable text formats. In this tutorial, we’ll create a speech recognition composable that will be reusable in your apps.

The API is initialized with the SpeechRecognition() constructor, which creates a new speech recognition object instance.

There are some important things to take note of when creating a composable, including naming conventions. Composable functions use camel casing, where the name starts with the prefix use. For example, our composable function for the demo would be named useSpeechRecognition.

Just like a regular function, a composable accepts parameters that can be used for functions that require dynamic data. It is best to return a refs object from composables. Therefore, the values will still retain their reactivity even when the composable is destructured for use in different components.

The basic structure of every composable is as follows:

export default function useComposableFunction() {
  // The logic
  return {// return values}
}

Let’s create the useSpeechRecognition composition function. In the composable folder, create a new file called useSpeechRecognition.js, then place the following logic functionality inside it:

import { ref,watch} from 'vue'

// the function accepts parameters
export function useSpeechRecognition({lang,continuous,interimResults}) {
    const isListening = ref(false)
    const isFinal = ref(false)
    const result = ref('')
    const error = ref(')

   // Intialize the web speech API
    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition
    // Checks if the browser supports the API
    const isSupported = Boolean(SpeechRecognition)
    // The speech recognition constructor
    const recognition = SpeechRecognition? new SpeechRecognition() : false

     // a function to set it for listening
    const start = () => {
      isListening.value = true
    }

     // a function to stop it from listening
    const stop = () => {
      isListening.value = false
    }

   // Checks if the browser supports
    if (isSupported) {
      recognition.continuous = continuous
      recognition.interimResults = interimResults
      recognition.lang = lang

      recognition.onstart = () => {
        isFinal.value = false
      }

      // the method to get the result of the transcription
      recognition.onresult = (event) => {
        // raw words that the user spoke
        const transcript = Array.from(event.results)
          .map((result) => {
            isFinal.value = result.isFinal
            return result[0]
          })
          .map(result => result.transcript)
          .join('')

        result.value = transcript
        error.value = undefined
      }

      // method to handle error
      recognition.onerror = (event) => {
        error.value = 'Speech recognition error detected: ' + event.error
      }

      recognition.onend = () => {
        isListening.value = false
      }

      watch(isListening, () => {
        if (isListening.value)
        // Starting the speech recognition
          recognition.start()
        else
        // stopping the recognition
          recognition.stop()
      })
    }
  }

Using the Web Speech API, we were able to create a function to accept voice sounds from a user and convert them into readable text. First, we ensured that our function accepts parameters, then initialized the Web Speech API, checking that is is supported by the browser. We added a function to check that our API is listening with isListening.value, setting the value to either true or false.

With the recognition.onresult method, we get the result of the transcription. Additionally, we added some error handling methods. This format saves us the stress of having to replicate this logic in different files depending on what we are building.

Next, we return the values and methods in an object:

    return {
      isSupported,
      isListening,
      isFinal,
      recognition,
      result,
      error,
      start,
      stop,
    }

Then, we use the composable in a component. In the App.vue file, we first import the following function:

import {useSpeechRecognition} from './composables/useSpeechRecognition'

By calling the function, we store the returned values from the composable. We also pass the parameter values:

const { isListening, isSupported, stop, result,start,error } = useSpeechRecognition({
        lang:'en-US',
        continuous: true,
        interimResults : true,
      })

With this set up, we then return the values from the composable that will be used in the component:

return {isListening,isSupported,stop,result,start,error}

Finally, we implement the function in our component:

<template>
  <div class="app">
    <div v-if="!isSupported">
      Your browser does not support SpeechRecognition API,
      <a
        href="https://caniuse.com/mdn-api_speechrecognition"
        target="_blank"
      >more details</a>
    </div>
    <div v-else >
      <header>
      <h1> Speech Recognition  </h1>
      <i class="header-icon fas fa-microphone-alt"></i>
    </header>
    <main>
      <div class="mic-buttons">
        <!-- To handle the controls -->
    <button v-if="!isListening" @click="start">
        Speak 
      </button>
      <button v-if="isListening" class="orange" @click="stop">
        Stop
      </button>
      </div>
      <h2> English Transcript </h2>
      <!-- Conditionals to handle errors -->
      <p v-if="error" >{{error}}</p>
      <div v-else>
      <textarea v-model="result" class="text-transcript" cols="30" rows="10">  </textarea>
      </div>
    </main>
    </div>
  </div>
</template>

Here’s the link to the complete code, in case you want to try it out.

With this composable, we are easily able to implement a speech recognition feature in our Vue apps that is also reusable for different functionalities.

External libraries for composable functions

An alternate approach for using composables in your Vue application is through external open source libraries, which are created to leverage custom composition API functions.

VueUse

Written fully in TypeScript, the VueUse library provides over 200 composable functions that work for both Vue 2 and 3 apps. The functions can be customized and used in your projects via the CDN or installed directly with npm:

npm i @vueuse/core

<script src="https://unpkg.com/@vueuse/core"></script>

The documentation is well written with interactive demos and code. The functions are categorized into nine types: Browser, Sensors, Animation, State, Elements, Component, Watch, Network, Utilities, and Misc. You can get more information about the different functions from the official documentation.

vue-composables

vue-composable is a library that provides ready-to-use, generic composition API functions. vue-composable is built fully with TypeScript and supports both Vue 2 and Vue 3 apps. You can install it using either Yarn or npm:

# install with yarn
yarn add @vue/composition-api vue-composable
# install with npm
npm install @vue/composition-api vue-composable

Some of the categories of functions that it provides are Events, Dates, Format, Breakpoint, Storage, i18n, and Web. You can learn more from the official documentation.

Conclusion

Composable functions extract the logic functionality separately to be reused across several other components, saving you the stress of having to replicate your code in multiple different instances to achieve the same result.

The concept behind composables changes the way we handle reusability in our applications, offering a simpler, flexible, and more efficient approach. Now is a good time to refactor your codebase to use composables in your applications!

If you have any questions, you can definitely reach out to me on Twitter or leave a comment below. Thanks for reading!

Experience your Vue apps exactly how a user does

Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket. https://logrocket.com/signup/

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens in your Vue apps including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.

The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error, and what state the application was in when an issue occurred.

Modernize how you debug your Vue apps - .

Abiola Farounbi Frontend developer and technical writer with a passion for open source, accessibility, and web technologies.

Leave a Reply