If you have worked with Vue 2, you are likely familiar with Mixins. While they allowed us to reuse code, they often led to “Mixin Hell”—where data sources became unclear and naming collisions were a nightmare. However, with the arrival of Vue 3 and the Composition API, we have a superior solution: Vue.js Composables.
In this guide, we will explore what Composables are, why they replace Mixins, and how you can write your first one today.
What are Vue.js Composables?
In simple terms, a “Composable” is a function that leverages Vue’s Composition API to encapsulate and reuse stateful logic.
Instead of scattering your logic across data, methods, and mounted like in the Options API, Composables allow you to group related logic into a single function. This makes your code cleaner, easier to read, and highly portable between components.
Read the official Vue.js documentation on Composables
Why you should stop using Mixins
You might be asking, “Why change if Mixins still work?” Here is the comparison:
- Source of Data: With Mixins, it is hard to tell where a property comes from (Implicit). With Vue.js Composables, you import exactly what you need (Explicit).
- Naming Collisions: Mixins can conflict if they use the same variable name. Composables avoid this entirely because you can rename variables upon destructuring.
Therefore, migrating to Composables is essential for maintaining a healthy codebase in the long run.
How to Build Your First Composable
Let’s build a simple but practical example: a useToggle composable. This is perfect for managing Modals, Sidebars, or Dropdowns.
Step 1: Create the logic file
Create a file named useToggle.js. Inside, we will use ref to hold the state and a function to modify it.
import { ref } from 'vue'
export function useToggle(initialValue = false) {
// 1. Create state
const isVisible = ref(initialValue)
// 2. Create logic to modify state
const toggle = () => {
isVisible.value = !isVisible.value
}
// 3. Return what is needed
return {
isVisible,
toggle
}
}
Step 2: Use it in your Component
Now, you can use this logic inside any component, such as NavBar.vue or LoginModal.vue.
<script setup>
import { useToggle } from './composables/useToggle'
// We can rename 'isVisible' to something meaningful like 'isModalOpen'
const { isVisible: isModalOpen, toggle } = useToggle(false)
</script>
<template>
<button @click="toggle">
{{ isModalOpen ? 'Close Modal' : 'Open Modal' }}
</button>
<div v-if="isModalOpen" class="modal">
<h1>Hello World</h1>
</div>
</template>
💡 Pro Tip: Notice how we renamed isVisible to isModalOpen. This flexibility is impossible with Mixins!
Taking it Further: The VueUse Library
Before you start writing Composables for everything (like Mouse tracking, LocalStorage, or Dark Mode), check if it already exists.
VueUse is a collection of essential Vue Composition Utilities. It provides hundreds of ready-to-use functions.
- useLocalStorage: Persist data in the browser.
- useDark: Handle Dark Mode easily.
- useMouse: Track mouse position.
Check out my guide on Vue.js Performance Optimization
Conclusion
Vue.js Composables are a game-changer for code organization. They solve the limitations of Mixins and allow developers to write cleaner, safer, and more modular code.
Start by refactoring your small logic pieces (like Toggles or Form handling) into Composables today. Your future self will thank you!
Do you prefer Composables or Mixins? Share your thoughts in the comments below!