0
0
Vueframework~15 mins

Composables for reusable logic in Vue - Deep Dive

Choose your learning style9 modes available
Overview - Composables for reusable logic
What is it?
Composables are special functions in Vue that let you share and reuse logic across different parts of your app. Instead of repeating the same code in many components, you put that code inside a composable. Then, any component can use that composable to get the same behavior or data. This makes your code cleaner and easier to maintain.
Why it matters
Without composables, developers often copy and paste code or use complex mixins that are hard to understand and debug. Composables solve this by making logic easy to share and test. This saves time, reduces bugs, and helps teams build bigger apps faster. Imagine fixing a bug once in a composable instead of many places.
Where it fits
Before learning composables, you should understand Vue's basic concepts like components, reactive state, and the Composition API. After mastering composables, you can explore advanced patterns like custom directives, plugins, and Vue's Server Components.
Mental Model
Core Idea
Composables are like reusable recipe cards that hold cooking steps you can use anytime to make the same dish without rewriting instructions.
Think of it like...
Think of composables as a toolbox with special tools you build once and carry everywhere. Instead of building a new tool for every project, you just grab the right tool from your box to get the job done quickly and consistently.
┌───────────────┐       ┌───────────────┐       ┌───────────────┐
│ Composable A  │──────▶│ Component 1   │       │ Component 2   │
│ (Reusable     │       │ (Uses logic   │       │ (Uses logic   │
│  logic)       │       │  from A)      │       │  from A)      │
└───────────────┘       └───────────────┘       └───────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding Vue Composition API Basics
🤔
Concept: Learn how Vue's Composition API lets you organize component logic using functions like reactive and ref.
Vue's Composition API introduces functions like ref() to create reactive data and reactive() for reactive objects. These let you track changes and update the UI automatically. Components use setup() to define this reactive logic.
Result
You can create reactive state inside components that updates the UI when changed.
Understanding reactive state is key because composables build on this to share logic across components.
2
FoundationWhat Are Composables in Vue?
🤔
Concept: Composables are plain functions that use Vue's reactive APIs to encapsulate and share logic.
A composable is a function that can call reactive(), ref(), computed(), or watch() inside it and returns reactive data or methods. Components call these functions inside setup() to reuse logic.
Result
You can write a composable once and use it in many components to share state or behavior.
Knowing composables are just functions helps remove confusion about special syntax or magic.
3
IntermediateCreating a Simple Composable Function
🤔Before reading on: do you think a composable must be a Vue component or just a plain function? Commit to your answer.
Concept: Learn how to write a composable that tracks window width reactively.
Example: function useWindowWidth() { const width = ref(window.innerWidth); window.addEventListener('resize', () => { width.value = window.innerWidth; }); return { width }; } Components can call useWindowWidth() inside setup() to get reactive width.
Result
Components using this composable reactively update when the window resizes.
Seeing a real composable shows how easy it is to package reactive logic for reuse.
4
IntermediateSharing State Safely with Composables
🤔Before reading on: do you think composables share the same state instance across components by default? Commit to yes or no.
Concept: Understand how composables create fresh state per component or share state globally.
By default, calling a composable creates new reactive state for each component. To share state, you can define reactive variables outside the composable function so all calls use the same instance.
Result
You control whether state is unique per component or shared app-wide.
Knowing this prevents bugs where components unexpectedly share or don't share data.
5
IntermediateUsing Lifecycle Hooks Inside Composables
🤔Before reading on: can composables use Vue lifecycle hooks like onMounted? Commit to yes or no.
Concept: Learn how composables can run code at specific component lifecycle moments.
Inside a composable, you can call lifecycle hooks like onMounted(), onUnmounted() to run setup or cleanup code when the component using the composable mounts or unmounts.
Result
Composables can manage side effects and cleanup automatically.
This lets composables handle complex logic like event listeners or timers cleanly.
6
AdvancedComposables with Parameters and Customization
🤔Before reading on: do you think composables can accept arguments to customize their behavior? Commit to yes or no.
Concept: Explore how to make composables flexible by passing parameters.
You can define composables that accept arguments to control their logic. For example, a useFetch(url) composable can fetch data from any URL passed in. This makes composables reusable in many contexts.
Result
Composables become powerful building blocks adaptable to many needs.
Parameterizing composables unlocks their full potential for code reuse.
7
ExpertAvoiding Common Pitfalls in Composable Design
🤔Before reading on: do you think composables should always be pure functions without side effects? Commit to yes or no.
Concept: Understand best practices and subtle traps when designing composables for production.
Composables often manage side effects like event listeners or timers. It's important to clean these up properly using lifecycle hooks to avoid memory leaks. Also, avoid sharing mutable state unintentionally between components unless explicitly desired.
Result
Well-designed composables are safe, predictable, and maintainable in large apps.
Knowing these pitfalls helps prevent bugs that are hard to trace in complex apps.
Under the Hood
Composables work by leveraging Vue's reactive system inside plain JavaScript functions. When you call a composable inside setup(), it creates reactive references or reactive objects that Vue tracks. Vue's reactivity system uses proxies to detect changes and update the DOM efficiently. Lifecycle hooks inside composables register callbacks tied to the component instance, ensuring proper setup and cleanup.
Why designed this way?
Vue introduced composables with the Composition API to solve problems with the older mixins and options API, which were hard to organize and reuse. Composables use plain functions to keep logic explicit and composable, avoiding name conflicts and improving TypeScript support. This design favors simplicity, flexibility, and better code organization.
┌───────────────┐
│ Component     │
│ setup()       │
│ calls         │
│ Composable()  │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Composable    │
│ creates       │
│ reactive refs │
│ and hooks     │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Vue Reactivity│
│ System tracks │
│ changes       │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: do you think composables automatically share state between components? Commit to yes or no.
Common Belief:Composables always share the same state across all components that use them.
Tap to reveal reality
Reality:By default, each component gets its own fresh state when calling a composable unless state is explicitly declared outside the function.
Why it matters:Assuming shared state can cause unexpected bugs where components do not update independently or overwrite each other's data.
Quick: do you think composables must be Vue components or special objects? Commit to yes or no.
Common Belief:Composables are special Vue components or require special syntax.
Tap to reveal reality
Reality:Composables are just plain JavaScript functions using Vue's reactive APIs inside setup().
Why it matters:Believing composables are complex or special can discourage beginners from using them or lead to overcomplicated code.
Quick: do you think composables should never have side effects like event listeners? Commit to yes or no.
Common Belief:Composables must be pure functions without side effects.
Tap to reveal reality
Reality:Composables often manage side effects but must clean them up properly using lifecycle hooks.
Why it matters:Ignoring side effect management can cause memory leaks or stale event handlers in apps.
Quick: do you think composables replace Vue components? Commit to yes or no.
Common Belief:Composables are an alternative to components and can replace them.
Tap to reveal reality
Reality:Composables only share logic; components still define UI and structure.
Why it matters:Misunderstanding this can lead to trying to build UI inside composables, which breaks Vue's design.
Expert Zone
1
Composables can be nested, meaning one composable can call another to build complex reusable logic layers.
2
Using composables with TypeScript requires careful typing of returned reactive data to get full type safety and autocompletion.
3
Shared state composables must handle concurrency and reactivity carefully to avoid race conditions in large apps.
When NOT to use
Avoid composables when logic is tightly coupled to a single component's UI or lifecycle and not reusable. For global state, consider Vuex or Pinia stores instead. Also, for very simple logic, inline setup code may be clearer than extracting a composable.
Production Patterns
In real apps, composables are used for data fetching, form handling, authentication, and integrating third-party APIs. Teams often create libraries of composables to standardize behavior and speed up development. Proper cleanup and testing of composables are critical in production.
Connections
Functional Programming
Composables build on the idea of pure functions and composition to create reusable logic blocks.
Understanding functional programming concepts helps grasp why composables are just functions and how to combine them cleanly.
React Hooks
Composables in Vue are similar to React Hooks as both share reusable logic using functions with reactive state.
Knowing React Hooks helps understand composables faster and vice versa, showing a common pattern in modern UI frameworks.
Modular Design in Engineering
Composables reflect modular design principles where complex systems are built from small, reusable parts.
Seeing composables as modules helps appreciate their role in maintainability and scalability beyond programming.
Common Pitfalls
#1Sharing reactive state unintentionally between components causing unexpected data changes.
Wrong approach:const state = reactive({ count: 0 }); function useCounter() { return { state }; } // All components share the same state instance
Correct approach:function useCounter() { const state = reactive({ count: 0 }); return { state }; } // Each component gets its own state
Root cause:Declaring reactive state outside the composable function shares it globally instead of per component.
#2Not cleaning up event listeners or timers inside composables causing memory leaks.
Wrong approach:function useResize() { window.addEventListener('resize', onResize); // No cleanup }
Correct approach:function useResize() { onMounted(() => window.addEventListener('resize', onResize)); onUnmounted(() => window.removeEventListener('resize', onResize)); }
Root cause:Ignoring Vue lifecycle hooks to manage side effects inside composables.
#3Trying to put UI rendering code inside composables.
Wrong approach:function useButton() { return () => h('button', 'Click me'); } // Using composable as UI component
Correct approach:function useButtonLogic() { const count = ref(0); function increment() { count.value++; } return { count, increment }; } // UI stays in component template
Root cause:Misunderstanding composables as UI components rather than logic containers.
Key Takeaways
Composables are plain functions that package reactive logic for reuse across Vue components.
They help keep code clean, avoid duplication, and make apps easier to maintain and test.
Each call to a composable creates fresh reactive state unless you explicitly share it outside the function.
Composables can use lifecycle hooks to manage side effects safely and clean up resources.
Understanding composables unlocks powerful patterns for building scalable Vue applications.