Vue Composables: what are they, and how to create & use one
Tags: vue, javascript, webdev, tutorial
Published: 2024-03-29 18:16:45

---
cover_image: https://i.gifer.com/1H4.gif
---

Hey there, fellow Vue enthusiasts! 🎉 Ever found yourself lost in the jungle of a Vue component, overwhelmed by its tangled mess of tasks? 🤯 We've all been there! Picture this: you start with a simple component, but as your project blossoms, so does the complexity. Before you know it, your once tidy component has morphed into a wild beast, hard to read, test, or reuse. 😱

![confused](https://www.icegif.com/wp-content/uploads/2023/08/icegif-546.gif)

Isn't it a pain when you're constantly scrolling up and down, trying to decipher what's happening? Or worse, when you find yourself copy-pasting the same logic across multiple components? Or testing a cascading waterfall of side effects? It's like a bad dream, isn't it? Fear not, my fellow brave coder! Vue.js to the rescue with its secret weapon: composables. 🦸‍♂️

### What Exactly Are Composables?

Think of composables as your code's trusty sidekick, always ready to swoop in and save the day! 🦸‍♀️ They're like little nuggets of wisdom, encapsulating reusable logic that you can sprinkle throughout your app. 🌟 In simpler terms, they're functions that return an object of goodies you can use in your Vue components. Neat, huh?

```javascript
// useVuei18n.js
import { useI18n } from 'vue-i18n'

export const useVuei18n = () => {
  const { t } = useI18n()

  return { t }
}
```

Now, you can sprinkle that `t` function magic in any component that imports the `useVuei18n` composable. Voila! ✨

```vue
<template>
  <div>{{ t('hello') }}</div>
</template>

<script setup>
import { useVuei18n } from './useVuei18n'

const { t } = useVuei18n()
</script>
```

### Let's Dive into an Example

Ready for some hands-on learning? Let's dive into an example together! Imagine we have a component fetching users from an API and filtering them by name. Sounds simple, right? Here's how it could look:

```vue
<template>
  <div>
    <input v-model="search" @input="searchUsers" />
    <ul>
      <li v-for="user in users" :key="user.id">{{ user.name }}</li>
    </ul>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const users = ref([])
const search = ref('')

const searchUsers = () => {
  // fetch users
  fetch('https://jsonplaceholder.typicode.com/users')
    .then(response => response.json())
    .then(data => {
      users.value = data.filter(user => user.name.includes(search.value))
    })
}

onMounted(searchUsers)
</script>
```

The component starts simple, but as it grows, it becomes a tangled mess. Fear not! We'll rescue it with a `useFetch` composable, splitting responsibilities and making our code cleaner and more focused. 👌

```javascript
// useFetch.js
import { ref } from 'vue'

export const useFetch = (url, data) => {
  const search = ref('')

  const searchUsers = () => {
    fetch(url)
      .then(response => response.json())
      .then(users => {
        data.value = users.filter(user => user.name.includes(search.value))
      })
  }

  return { search, searchUsers }
}
```

Now, let's sprinkle some `useFetch` magic in our component:

```vue
<template>
  <div>
    <input v-model="search" @input="searchUsers" />
    <ul>
      <li v-for="user in users" :key="user.id">{{ user.name }}</li>
    </ul>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useFetch } from './useFetch'

const users = ref([])

const { search, searchUsers } = useFetch('https://jsonplaceholder.typicode.com/users', users)

onMounted(searchUsers)
</script>
```

We went from a component that juggles two tasks to a clean and focused setup: one task for the component and one for the composable. It's like a breath of fresh air, isn't it? 🌬️ And that's the beauty of composables! They keep your codebase tidy and your components happy. 🎈 Even your cat will thank you later. 🐈‍⬛

![tom cat relieved](https://www.icegif.com/wp-content/uploads/icegif-546.gif)

### Composables: Behind the Scenes

Curious about how composables work under the hood? Buckle up, because we're diving into the nitty-gritty details! 🕵️‍♂️ When you import a composable, it springs into action like a trusty sidekick 🦸‍♂️, executing once and caching its properties. This ensures efficiency and prevents messy side effects. Plus, composables are reactive! 🔄 They respond to changes, ensuring your components stay in sync with the data.

```vue
<template>
  <div>{{ $t('hello') }}</div>
</template>

<script setup>
import { useI18n } from 'vue-i

18n'

const { t: $t } = useI18n()

console.log('composable executed')
</script>
```

Click that button, and watch the magic happen! The composable springs back to life, reacting to changes like a champ. 🎉 Because let's face it, what's Vue.js without that sweet, sweet reactivity?

![all over again, deja vu](https://y.yarn.co/244db8da-b52b-454e-9626-e2eaebd38dc8_text.gif)

Also, performance speaking, composables also help you avoid unnecessary re-renders. By splitting your logic into composables, you can ensure that only the relevant parts of your component re-render when the data changes. 🚀 It would be pretty annoying if your entire component re-rendered every time you typed a single letter, wouldn't it?

### When not to use Composables

While composables are a powerful tool in your Vue.js arsenal, there are times when you should think twice before using them. 🤔 For instance, if you're working on a small project or a one-off component, composables might be overkill. 🛠️ Instead, keep it simple and stick to the basics. Also, if you're dealing with a component that's tightly coupled with its logic, you might not need a composable. 🤝 Sometimes, it's okay to keep things together if they work well as a team. Take an example of a simple button component that toggles a modal. It's small, simple, and doesn't need to be split into a composable. 🛑

```vue
<template>
  <button @click="toggleModal">Open Modal</button>
  <Modal v-if="showModal" @close="toggleModal" />
</template>

<script setup>
import { ref } from 'vue'

const showModal = ref(false)

const toggleModal = () => {
  showModal.value = !showModal.value
}

</script>
```

If you put the `toggleModal` function in a composable, it would make the component more complex than it needs to be. 🤯 So, remember, composables are great, but use them wisely! 🧠

### Wrapping Up

And there you have it, folks! Composables: the unsung heroes of Vue.js development. 🦸‍♀️ Give it a try, and you will thank yourself later! Happy coding!😁

### Resources

- [Vue 3 Composition API](https://v3.vuejs.org/guide/composition-api-introduction.html)
- [Vue 3 Script Setup](https://v3.vuejs.org/api/sfc-script-setup.html)
- [Vue 3 Composables](https://v3.vuejs.org/guide/composition-api-introduction.html#composables)
- [Vue 3 Composables with TypeScript](https://v3.vuejs.org/guide/typescript-support.html#using-composition-api)
- [Vue 3 Composables with Vite](https://v3.vuejs.org/guide/typescript-support.html#using-vite)

### About the Author

I'm a frontend developer and technical writer based in Portugal. I'm passionate about software engineering 👨‍💻, and I love to explore new tools in my day-to-day. You can find me on [GitHub](github.com/bcostaaa01). If you have any questions or feedback, feel free to reach out! 🚀