0
0
Vueframework~15 mins

Composable accepting parameters in Vue - Deep Dive

Choose your learning style9 modes available
Overview - Composable accepting parameters
What is it?
A composable in Vue is a reusable function that encapsulates logic and state. When a composable accepts parameters, it means you can customize its behavior or data by passing values into it. This makes composables flexible and adaptable for different parts of your app. Instead of repeating code, you write once and adjust with parameters.
Why it matters
Without composables that accept parameters, you would need to write many similar functions for each use case, causing repetition and harder maintenance. Parameterized composables let you share logic easily while tailoring it to specific needs. This saves time, reduces bugs, and keeps your code clean and organized.
Where it fits
Before learning this, you should understand Vue 3 basics, especially the Composition API and reactive state with ref and reactive. After mastering parameterized composables, you can explore advanced patterns like composable factories, dependency injection, and testing composables.
Mental Model
Core Idea
A composable accepting parameters is like a recipe that takes ingredients to produce a customized dish every time you use it.
Think of it like...
Imagine a coffee machine where you can choose how strong or sweet you want your coffee each time. The machine is the composable, and the strength and sweetness settings are the parameters you pass in to get your perfect cup.
Composable Function
┌─────────────────────────────┐
│ function useFeature(params) │
│ ┌─────────────────────────┐ │
│ │ Uses params to customize │ │
│ │ reactive state & logic   │ │
│ └─────────────────────────┘ │
│ Returns reactive data &     │
│ methods based on params     │
└─────────────────────────────┘
Build-Up - 7 Steps
1
FoundationWhat is a Vue composable?
🤔
Concept: Introduces the idea of composables as reusable functions for logic and state.
In Vue 3, a composable is a function that uses Vue's reactive features like ref or reactive to hold state or logic. For example, a composable might track a counter or fetch data. You call it inside your component's setup() to reuse that logic.
Result
You get a function that bundles reactive state and methods you can reuse in many components.
Understanding composables is key because they let you organize and share logic cleanly without repeating code.
2
FoundationHow to pass parameters to functions
🤔
Concept: Shows how normal JavaScript functions accept parameters to customize behavior.
Functions in JavaScript can take inputs called parameters. For example, function greet(name) { return `Hello, ${name}`; } When you call greet('Anna'), it returns 'Hello, Anna'. This lets one function work differently depending on input.
Result
You can create flexible functions that do different things based on what you pass in.
Knowing how parameters work in functions is essential before applying this to composables.
3
IntermediateCreating a composable with parameters
🤔Before reading on: do you think passing parameters to a composable changes its internal reactive state or just static values? Commit to your answer.
Concept: Combines composables and parameters to customize reactive state or logic inside the composable.
You can define a composable function that takes parameters to set initial state or control behavior. For example: function useCounter(initialValue = 0) { const count = ref(initialValue); function increment() { count.value++; } return { count, increment }; } Calling useCounter(5) starts count at 5, while useCounter() starts at 0.
Result
Each time you call the composable with different parameters, you get a customized reactive state instance.
Passing parameters lets you create flexible composables that adapt to different needs without rewriting logic.
4
IntermediateUsing reactive parameters inside composables
🤔Before reading on: do you think parameters passed to a composable can be reactive refs themselves? Commit to your answer.
Concept: Explains how composables can accept reactive refs or reactive objects as parameters to track changes dynamically.
Parameters to composables can be reactive. For example: function useToggle(state) { function toggle() { state.value = !state.value; } return { state, toggle }; } If you pass a ref like const isOpen = ref(false), the composable can toggle it directly. This means composables can work with reactive data from outside.
Result
Composable reacts to changes in reactive parameters and can modify them, enabling shared reactive state.
Accepting reactive parameters allows composables to integrate tightly with component state and other composables.
5
IntermediateDefault parameters and destructuring in composables
🤔
Concept: Shows how to use default values and object destructuring for clearer, flexible parameter handling.
You can define composables with default parameter values and destructure objects for clarity: function useFetch({ url, method = 'GET' }) { const data = ref(null); // fetch logic here return { data }; } Calling useFetch({ url: '/api' }) uses GET by default. This pattern makes composables easier to use and extend.
Result
Composable parameters become more readable and maintainable with defaults and destructuring.
Using defaults and destructuring helps manage many parameters cleanly and prevents errors.
6
AdvancedParameter-driven composable factories
🤔Before reading on: do you think a composable can return another composable customized by parameters? Commit to your answer.
Concept: Introduces composable factories that create composables dynamically based on parameters.
Sometimes you want a function that returns a composable tailored by parameters. For example: function createUseList(apiEndpoint) { return function useList() { const items = ref([]); // fetch from apiEndpoint return { items }; }; } const useUserList = createUseList('/users'); const useProductList = createUseList('/products'); This pattern helps generate many similar composables with different data sources.
Result
You get composables customized at creation time, improving code reuse and separation.
Understanding composable factories unlocks powerful patterns for scalable Vue apps.
7
ExpertHandling parameter changes reactively inside composables
🤔Before reading on: if a parameter changes after composable creation, do you think the composable automatically updates? Commit to your answer.
Concept: Explains how to watch reactive parameters inside composables to respond to changes dynamically.
If a composable receives reactive parameters, it can watch them to update internal state: function useDataLoader(urlRef) { const data = ref(null); watch(urlRef, async (newUrl) => { data.value = await fetch(newUrl).then(r => r.json()); }, { immediate: true }); return { data }; } This way, when urlRef changes, the composable reloads data automatically.
Result
Composable stays in sync with changing parameters, enabling dynamic behavior.
Knowing how to watch parameters inside composables is crucial for building responsive, real-world features.
Under the Hood
When you call a composable with parameters, Vue runs the function creating new reactive refs or reactive objects inside it. These reactive objects track dependencies and notify Vue's reactivity system on changes. If parameters are reactive refs, the composable can watch or use them directly, linking external state with internal logic. Vue's reactivity system uses proxies and dependency tracking to update components efficiently when reactive data changes.
Why designed this way?
Vue's Composition API was designed to improve code reuse and organization over the older Options API. Accepting parameters in composables allows developers to write flexible, modular logic that can be customized per use. This design avoids duplication and encourages separation of concerns. Alternatives like global state or mixins were less flexible or caused naming conflicts, so parameterized composables provide a clean, scalable solution.
Call composable(params)
┌─────────────────────────────┐
│ Composable function runs    │
│ ┌─────────────────────────┐ │
│ │ Creates reactive state   │ │
│ │ Uses params to customize│ │
│ │ Watches reactive params │ │
│ └─────────────────────────┘ │
│ Returns reactive objects    │
└─────────────┬───────────────┘
              │
              ▼
       Vue reactivity system
┌─────────────────────────────┐
│ Tracks dependencies         │
│ Updates components on change│
└─────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does passing a primitive parameter to a composable make it reactive inside? Commit yes or no.
Common Belief:Passing any parameter to a composable automatically makes it reactive inside.
Tap to reveal reality
Reality:Only reactive refs or reactive objects passed as parameters are reactive inside. Primitives like numbers or strings are copied and not reactive.
Why it matters:Assuming primitives are reactive can cause bugs where UI does not update when expected.
Quick: If you call a composable twice with the same parameters, do you get shared state? Commit yes or no.
Common Belief:Calling a composable multiple times with the same parameters shares the same reactive state instance.
Tap to reveal reality
Reality:Each call to a composable creates a new independent reactive state, even with identical parameters.
Why it matters:Expecting shared state can lead to confusing bugs where changes in one place don't reflect elsewhere.
Quick: Can you change parameters inside a composable and expect the caller's variables to update? Commit yes or no.
Common Belief:Changing parameters inside a composable updates the original variables passed in.
Tap to reveal reality
Reality:Only if the parameters are reactive refs or objects. For primitives or non-reactive values, changes inside the composable do not affect the caller.
Why it matters:Misunderstanding this causes unexpected behavior and state desynchronization.
Quick: Does a composable automatically update if a non-reactive parameter changes externally? Commit yes or no.
Common Belief:Composables automatically react to any parameter changes, reactive or not.
Tap to reveal reality
Reality:Only reactive parameters trigger updates inside composables. Non-reactive parameters are fixed at call time.
Why it matters:Assuming automatic updates can cause stale data and UI inconsistencies.
Expert Zone
1
Passing reactive parameters can create tight coupling between composable and caller, which may complicate testing and reuse if not managed carefully.
2
Using composable factories allows creating specialized composables but can increase bundle size if overused without code-splitting.
3
Watching parameters inside composables requires careful cleanup to avoid memory leaks, especially when composables are used in many components.
When NOT to use
Avoid parameterized composables when the logic is simple and used only once; a local reactive state inside the component may be clearer. For global shared state, use Vuex or Pinia instead. Also, if parameters are complex and deeply nested, consider using reactive stores or provide/inject for better management.
Production Patterns
In real apps, parameterized composables are used for form handling with dynamic fields, API data fetching with variable endpoints, and feature toggles where behavior changes based on parameters. Factories generate composables for different resource types. Watching reactive parameters enables live updates without reloading components.
Connections
Functional Programming
Composable functions with parameters follow the same principle of pure functions with inputs and outputs.
Understanding that composables are like pure functions helps write predictable, testable Vue logic.
Dependency Injection
Passing parameters to composables is a form of injecting dependencies to customize behavior.
Recognizing this connection clarifies how to design composables for flexibility and decoupling.
Cooking Recipes
Like recipes take ingredients to produce dishes, composables take parameters to produce reactive logic.
This cross-domain view reinforces the mental model of customization and reuse.
Common Pitfalls
#1Passing a non-reactive primitive and expecting reactive updates.
Wrong approach:function useCounter(start) { const count = ref(start); // later expecting count to update if start changes } const start = 0; const { count } = useCounter(start); start = 5; // count.value does NOT update
Correct approach:const start = ref(0); function useCounter(startRef) { const count = ref(startRef.value); watch(startRef, val => { count.value = val; }); return { count }; } const { count } = useCounter(start); start.value = 5; // count.value updates
Root cause:Primitives are copied by value, so changes outside do not reflect inside unless wrapped in reactive refs.
#2Mutating a parameter inside composable assuming caller's variable changes.
Wrong approach:function useToggle(flag) { flag = !flag; // tries to toggle } let isOpen = false; useToggle(isOpen); console.log(isOpen); // still false
Correct approach:function useToggle(flagRef) { flagRef.value = !flagRef.value; } const isOpen = ref(false); useToggle(isOpen); console.log(isOpen.value); // toggled
Root cause:Only reactive refs allow mutation that affects the original variable; primitives are passed by value.
#3Calling composable outside setup or component context expecting reactivity.
Wrong approach:const { count } = useCounter(0); // used outside Vue component console.log(count.value); // reactive but no component to update
Correct approach:Inside setup() { const { count } = useCounter(0); return { count }; } // ensures reactivity links to component lifecycle
Root cause:Composables rely on Vue's reactivity system active inside component setup; outside, reactivity has no effect on UI.
Key Takeaways
Composable functions in Vue can accept parameters to customize their reactive state and behavior, making them flexible and reusable.
Parameters can be simple values or reactive refs; understanding the difference is crucial for correct reactivity.
Using default parameters and destructuring improves composable usability and clarity.
Watching reactive parameters inside composables enables dynamic updates and responsive features.
Advanced patterns like composable factories help generate specialized composables for scalable applications.