Vue Composables: what are they, and how to create & use one
Bruno
Posted on March 29, 2024
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. π±
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 }
}
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>
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>
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 }
}
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>
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. πββ¬
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>
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?
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>
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
- Vue 3 Script Setup
- Vue 3 Composables
- Vue 3 Composables with TypeScript
- Vue 3 Composables with 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. If you have any questions or feedback, feel free to reach out! π
Posted on March 29, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.