Bird
Raised Fist0
Vueframework~15 mins

Composable accepting parameters in Vue - Deep Dive

Choose your learning style10 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.

Practice

(1/5)
1.

What is the main purpose of passing parameters to a Vue composable function?

easy
A. To customize the composable's behavior for different uses
B. To make the composable function run only once
C. To prevent the composable from using Vue's reactivity
D. To automatically render a template inside the composable

Solution

  1. Step 1: Understand composable functions

    Composable functions are reusable pieces of logic in Vue that can be shared across components.
  2. Step 2: Role of parameters in composables

    Parameters allow passing different inputs to the composable so it can behave differently depending on the need.
  3. Final Answer:

    To customize the composable's behavior for different uses -> Option A
  4. Quick Check:

    Parameters customize composables = A [OK]
Hint: Parameters let composables adapt to different inputs [OK]
Common Mistakes:
  • Thinking composables run only once
  • Believing parameters disable reactivity
  • Confusing composables with templates
2.

Which of the following is the correct way to define a composable that accepts a parameter initialCount?

function useCounter(???) {
  const count = ref(initialCount)
  return { count }
}
easy
A. useCounter((initialCount))
B. useCounter()
C. useCounter(initialCount)
D. useCounter(initialCount: number)

Solution

  1. Step 1: Check JavaScript function parameter syntax

    In JavaScript, function parameters are named without types or parentheses inside the parentheses.
  2. Step 2: Match parameter name with usage

    The parameter initialCount must be declared inside the parentheses as initialCount.
  3. Final Answer:

    useCounter(initialCount) -> Option C
  4. Quick Check:

    Function parameter syntax = D [OK]
Hint: Function parameters go inside parentheses without types [OK]
Common Mistakes:
  • Adding types like in TypeScript without syntax
  • Using parentheses inside parameter list
  • Leaving parameters empty when needed
3.

Given this composable and usage, what will be logged?

import { ref } from 'vue'
function useGreeting(name) {
  const greeting = ref(`Hello, ${name}!`)
  return { greeting }
}

const { greeting } = useGreeting('Alice')
console.log(greeting.value)
medium
A. undefined
B. "Hello, Alice!"
C. "Hello, name!"
D. Error: greeting is not defined

Solution

  1. Step 1: Understand parameter passing

    The composable receives 'Alice' as the name parameter, so the greeting string becomes "Hello, Alice!".
  2. Step 2: Accessing the ref value

    The greeting is a ref, so to get the string, we use greeting.value, which logs "Hello, Alice!".
  3. Final Answer:

    "Hello, Alice!" -> Option B
  4. Quick Check:

    Ref .value logs "Hello, Alice!" = C [OK]
Hint: Use .value to get ref content in Vue composables [OK]
Common Mistakes:
  • Logging the ref object instead of its value
  • Confusing parameter name with string literal
  • Forgetting to import ref from 'vue'
4.

Identify the error in this composable that accepts a parameter start:

import { ref } from 'vue'
function useTimer(start) {
  const time = ref(start)
  function increment() {
    time++
  }
  return { time, increment }
}
medium
A. Cannot increment a ref directly with ++ operator
B. Missing return statement for increment function
C. Parameter start is not reactive
D. Ref should be initialized with 0, not start

Solution

  1. Step 1: Check how ref values are updated

    Refs hold their value inside the .value property, so you cannot increment the ref itself.
  2. Step 2: Identify correct increment syntax

    The increment function should update time.value++ instead of time++.
  3. Final Answer:

    Cannot increment a ref directly with ++ operator -> Option A
  4. Quick Check:

    Update ref via .value, not ref itself = B [OK]
Hint: Use .value to update ref, not the ref variable itself [OK]
Common Mistakes:
  • Trying to increment ref without .value
  • Thinking parameters must be reactive
  • Forgetting to return functions from composable
5.

You want a composable useFilteredList that accepts an array and a filter function as parameters. Which implementation correctly applies the filter reactively?

import { computed } from 'vue'

function useFilteredList(list, filterFn) {
  const filtered = computed(() => ??? )
  return { filtered }
}

What should replace ????

hard
A. list.filter(filterFn)
B. filterFn(list)
C. computed(() => list.filter(filterFn))
D. list.value.filter(filterFn)

Solution

  1. Step 1: Understand composable parameters

    The list parameter is expected to be a ref(array) for proper reactivity in Vue composables.
  2. Step 2: Reactive filtering with computed

    Inside the computed, access the array value with list.value.filter(filterFn) to apply the filter reactively whenever the list changes.
  3. Final Answer:

    list.value.filter(filterFn) -> Option D
  4. Quick Check:

    computed(() => list.value.filter(filterFn)) = C [OK]
Hint: Use computed(() => list.value.filter(fn)) for reactive filtering [OK]
Common Mistakes:
  • Using list.filter(filterFn) without .value when list is ref
  • Calling filterFn(list) instead of list.filter(filterFn)
  • Unnecessarily nesting computed inside computed
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard