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! ๐
Top comments (0)