DEV Community

Cover image for Vue Composables: what are they, and how to create & use one
Bruno
Bruno

Posted on

Vue Composables: what are they, and how to create & use one

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

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?

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

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

  return { t }
}
✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน ✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน

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

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

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

const { t } = useVuei18n()
</script>
✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน ✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน

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:

<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>
✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน ✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน

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. 👌

// 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 }
}
✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน ✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน

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

<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>
✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน ✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน

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

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.

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

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

18n'

const { t: $t } = useI18n()

console.log('composable executed')
</script>
✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน ✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน

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

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. 🛑

<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>
✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน ✨ อัปเดตล่าสุด: bcostaaa/vue composables what are they and how to create use one b - ประเด็นร้อน

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

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. If you have any questions or feedback, feel free to reach out! 🚀

Top comments (0)