Bird
Raised Fist0
Vueframework~10 mins

Sharing composables across components in Vue - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Sharing composables across components
Create composable function
↓
Export composable
↓
Import composable in Component A
↓
Use composable in Component A setup
↓
Import composable in Component B
↓
Use composable in Component B setup
↓
Components share reactive state or logic
↓
UI updates based on shared composable
This flow shows how a composable function is created once, then imported and used in multiple Vue components to share reactive logic or state.
Execution Sample
Vue
import { ref } from 'vue'

export function useCounter() {
  const count = ref(0)
  function increment() { count.value++ }
  return { count, increment }
}
Defines a composable that provides a reactive count and an increment function to share across components.
Execution Table
StepActionComposable StateComponent A StateComponent B StateOutput/Effect
1Import useCounter in Component Acount=0count=0-No UI change yet
2Call useCounter() in Component A setupcount=0count=0-Component A shows count 0
3Import useCounter in Component Bcount=0count=0count=0No UI change yet
4Call useCounter() in Component B setupcount=0count=0count=0Component B shows count 0
5Component A calls increment()count=0 (separate)count=1count=0Component A updates to 1, B stays 0
6Component B calls increment()count=0 (separate)count=1count=1Component B updates to 1, A stays 1
7Components have independent statescount separate per callcount=1count=1UI reflects independent counts
8Modify composable to share state (singleton pattern)count=0 sharedcount=0count=0Both components start at 0 shared
9Component A calls increment() on shared statecount=1 sharedcount=1count=1Both components update to 1
10Component B calls increment() on shared statecount=2 sharedcount=2count=2Both components update to 2
11End---Shared state updates both components synchronously
💡 Execution stops after showing both independent and shared state usage in composables.
Variable Tracker
VariableStartAfter Step 2After Step 5After Step 6After Step 9After Step 10Final
Component A count-011122
Component B count--01122
Composable count (independent)0000---
Composable count (shared)0---122
Key Moments - 3 Insights
Why do Component A and Component B have different counts after calling increment() when using the composable normally?
Because each call to the composable function creates a new independent reactive state, so increments affect only that component's count (see execution_table rows 5 and 6).
How can we make the composable share state between components?
By defining the reactive state outside the composable function so it acts as a singleton shared across imports (see execution_table rows 8-10).
What happens to the UI when the shared state increments in one component?
Both components update their displayed count because they reference the same reactive state (see execution_table rows 9 and 10).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 5. What is Component B's count value?
A1
B0
C-
D2
💡 Hint
Check the 'Component B State' column at step 5 in the execution_table.
At which step do both components start sharing the same count state?
AStep 8
BStep 2
CStep 6
DStep 10
💡 Hint
Look for when the composable count is marked as 'shared' in the execution_table.
If the composable state is shared, what will Component A's count be after Component B calls increment() at step 10?
A1
B0
C2
DDoes not change
💡 Hint
Refer to the 'Component A State' column at step 10 in the execution_table.
Concept Snapshot
Sharing composables across components:
- Create composable function returning reactive state and methods.
- Import and call composable in multiple components.
- Each call creates independent state by default.
- To share state, define reactive variables outside the function.
- Shared state updates reflect in all components using it.
Full Transcript
This visual execution shows how Vue composables can be shared across components. First, a composable function is created that returns a reactive count and an increment method. When each component calls this composable, it gets its own independent reactive state, so increments affect only that component. This is shown in steps 1 to 7. Then, by moving the reactive state outside the composable function, the state becomes shared (singleton). Steps 8 to 11 show that when one component increments the count, both components see the updated value. This teaches how to share logic and state using composables in Vue.

Practice

(1/5)
1. What is the main purpose of a composable in Vue 3?
function useCounter() { const count = ref(0); return { count }; }
easy
A. To register global Vue directives
B. To define a new component template
C. To style components with CSS
D. To share reusable reactive logic across multiple components

Solution

  1. Step 1: Understand what a composable function does

    A composable is a function that returns reactive state or methods to be reused.
  2. Step 2: Identify the purpose of the example composable

    The example returns a reactive count variable to share logic across components.
  3. Final Answer:

    To share reusable reactive logic across multiple components -> Option D
  4. Quick Check:

    Composable = reusable logic [OK]
Hint: Composable functions return reactive state for reuse [OK]
Common Mistakes:
  • Thinking composables define templates
  • Confusing composables with CSS styling
  • Assuming composables register directives
2. Which is the correct way to import and use a composable named useTimer inside a Vue component's setup() function?
easy
A. import { useTimer } from './composables'; const { time } = useTimer();
B. import useTimer from './composables'; const time = useTimer;
C. const useTimer = require('./composables'); const { time } = useTimer();
D. import useTimer from './composables'; setup() { return useTimer; }

Solution

  1. Step 1: Import the composable correctly

    Use ES module import syntax with curly braces if composable is a named export.
  2. Step 2: Call the composable function inside setup()

    Call useTimer() to get reactive state, then destructure needed properties.
  3. Final Answer:

    import { useTimer } from './composables'; const { time } = useTimer(); -> Option A
  4. Quick Check:

    Import named + call function = correct usage [OK]
Hint: Import named composable and call it inside setup() [OK]
Common Mistakes:
  • Using require() instead of import
  • Not calling the composable function
  • Importing default when composable is named export
3. Given this composable and component code, what will be logged?
// composable.js
import { ref } from 'vue';
export function useCount() {
  const count = ref(0);
  function increment() { count.value++; }
  return { count, increment };
}

// Component.vue
import { useCount } from './composable';
export default {
  setup() {
    const { count, increment } = useCount();
    increment();
    increment();
    console.log(count.value);
    return {};
  }
}
medium
A. 2
B. 0
C. undefined
D. Error: count is not defined

Solution

  1. Step 1: Analyze composable logic

    Count starts at 0 and increments by 1 each time increment() is called.
  2. Step 2: Trace component setup execution

    Increment is called twice, so count.value becomes 2, then logged.
  3. Final Answer:

    2 -> Option A
  4. Quick Check:

    Two increments = count 2 [OK]
Hint: Count increments twice, so value is 2 [OK]
Common Mistakes:
  • Forgetting to call increment()
  • Confusing ref with plain variable
  • Expecting count to be 0 without increments
4. Identify the error in this composable usage:
import { ref } from 'vue';
export function useData() {
  const data = ref(null);
  fetch('/api').then(res => res.json()).then(json => data = json);
  return { data };
}
medium
A. Using ref instead of reactive
B. Missing await keyword before fetch
C. Reassigning the ref variable instead of its value
D. Not returning the data variable

Solution

  1. Step 1: Check how ref is updated

    Ref variables must update their .value, not be reassigned.
  2. Step 2: Identify the mistake in the fetch callback

    The code assigns data = json instead of data.value = json.
  3. Final Answer:

    Reassigning the ref variable instead of its value -> Option C
  4. Quick Check:

    Update ref.value, not ref itself [OK]
Hint: Update ref.value, not the ref variable [OK]
Common Mistakes:
  • Assigning directly to ref variable
  • Forgetting to handle async properly
  • Confusing reactive with ref usage
5. You want to share a composable that tracks a user's online status across multiple components. Which approach ensures each component has its own independent reactive state?
hard
A. Export a single reactive object and import it directly in all components
B. Export a function that returns new refs each call, then import and call it in each component
C. Define reactive state inside a global variable outside the composable
D. Use a Vuex store instead of composables for reactive state

Solution

  1. Step 1: Understand independent reactive state per component

    Each component needs its own fresh reactive refs to avoid shared state.
  2. Step 2: Identify correct composable pattern

    Exporting a function that returns new refs each call creates isolated state per component.
  3. Final Answer:

    Export a function that returns new refs each call, then import and call it in each component -> Option B
  4. Quick Check:

    Function returns fresh state per call [OK]
Hint: Return new refs inside function for isolated state [OK]
Common Mistakes:
  • Sharing a single reactive object causing shared state
  • Using global variables outside composables
  • Confusing Vuex with composables for local state
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