Parent component provides a shared reactive state 'selected' to its children via Vue's provide/inject.
Execution Table
Step
Action
State Before
State After
Effect
1
Parent creates reactive 'selected' = null
N/A
selected = null
Shared state ready
2
Parent calls provide('selected', selected)
selected = null
selected provided
Children can access 'selected'
3
Child1 injects 'selected'
selected provided
selected injected
Child1 can read/write 'selected'
4
Child2 injects 'selected'
selected provided
selected injected
Child2 can read/write 'selected'
5
Child1 updates selected.value = 'A'
selected = null
selected = 'A'
All children see selected = 'A'
6
Child2 reads selected.value
selected = 'A'
selected = 'A'
Child2 reacts to selected = 'A'
7
Child3 injects 'selected'
selected = 'A'
selected injected
Child3 sees selected = 'A'
8
Child3 updates selected.value = 'B'
selected = 'A'
selected = 'B'
All children see selected = 'B'
9
Parent and children re-render with selected = 'B'
selected = 'B'
selected = 'B'
UI updates to reflect selection
10
Execution ends
selected = 'B'
selected = 'B'
Pattern complete
💡 Execution stops after children update and react to shared state changes.
Variable Tracker
Variable
Start
After Step 1
After Step 5
After Step 8
Final
selected.value
null
null
'A'
'B'
'B'
Key Moments - 3 Insights
Why do children share the same 'selected' state?
Because the parent uses provide() to share a single reactive 'selected' object, all children inject() the same reference, so updates by one child affect all others (see execution_table steps 2, 3, 5, 8).
What happens if a child updates 'selected.value'?
The update changes the shared reactive state, triggering reactivity in all components that use it, causing UI updates (see execution_table steps 5, 6, 8, 9).
Can children work independently without the parent providing state?
No, children rely on the parent to provide the shared state via provide/inject. Without it, inject() returns undefined and reactivity breaks (see execution_table step 3).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the value of 'selected.value' after step 5?
A'B'
B'A'
Cnull
Dundefined
💡 Hint
Check the 'State After' column at step 5 in the execution_table.
At which step do all children see the updated 'selected' value 'B'?
AStep 5
BStep 3
CStep 8
DStep 1
💡 Hint
Look for when 'selected' changes to 'B' and children react in the execution_table.
If the parent did not call provide(), what would happen at step 3?
AChild1 would inject 'selected' as undefined
BChild1 would create its own 'selected'
CChild1 would throw an error
DChild1 would receive null
💡 Hint
Refer to the explanation in key_moments about provide/inject dependency.
Concept Snapshot
Compound components pattern in Vue:
- Parent uses provide() to share reactive state
- Children use inject() to access shared state
- Children update shared state to communicate
- All components reactively update UI together
- Enables flexible, coordinated component design
Full Transcript
The compound components pattern in Vue lets a parent component hold shared reactive state and pass it to child components using provide and inject. The parent creates a reactive variable, for example 'selected', and calls provide to share it. Child components call inject to access the same reactive variable. When one child updates the shared state, all children and the parent reactively update their UI to reflect the change. This pattern allows multiple components to work together as one unit by sharing state without passing props explicitly. The execution table shows step-by-step how the parent creates and provides the state, children inject and update it, and how the UI updates accordingly. Key moments clarify why children share the same state and what happens if the parent does not provide it. The visual quiz tests understanding of state changes and provide/inject behavior. This pattern helps build flexible, coordinated Vue components.
Practice
(1/5)
1. What is the main purpose of the compound components pattern in Vue?
easy
A. To group related UI parts inside one main component for better organization
B. To create multiple unrelated components in one file
C. To avoid using provide and inject for state sharing
D. To write components without any communication between them
Solution
Step 1: Understand the pattern goal
The compound components pattern groups related UI parts to work together inside one main component.
Step 2: Compare options
Only To group related UI parts inside one main component for better organization correctly describes grouping related UI parts for better organization and communication.
Final Answer:
To group related UI parts inside one main component for better organization -> Option A
Quick Check:
Compound components group related parts = B [OK]
Hint: Think: grouping related UI parts inside one component [OK]
Common Mistakes:
Confusing unrelated components grouping
Ignoring state sharing between parts
Thinking it avoids provide/inject
2. Which Vue feature is commonly used to share state between compound components?
easy
A. provide and inject
B. props
C. v-model
D. emit events
Solution
Step 1: Identify state sharing methods
Vue offers several ways to share data, but for compound components, provide and inject are designed for parent-child communication without prop drilling.
Step 2: Match pattern usage
Compound components use provide/inject to share state internally, unlike props or emit which are for direct parent-child or event communication.
Final Answer:
provide and inject -> Option A
Quick Check:
State sharing in compound components = provide/inject [OK]
Hint: Remember: provide/inject share state inside compound components [OK]
Common Mistakes:
Choosing props which require manual passing
Confusing emit with state sharing
Thinking v-model is for internal state sharing
3. Given this Vue compound component setup, what will be the rendered output?
C. The 'open' variable is not returned from setup in Dropdown
D. The 'open' ref is not reactive inside DropdownToggle
Solution
Step 1: Check inject handling in Options API
Injected refs via inject: ['open'] are not auto-unwrapped in Options API templates. 'open' is the ref object.
Step 2: Understand mutation and reactivity issue
@click="open = !open" reassigns a boolean to the ref variable (breaks link to original ref) and lacks .value access, making the ref unusable reactively as boolean state.
Final Answer:
The 'open' ref is not reactive inside DropdownToggle -> Option D
Quick Check:
Options API injected ref needs .value [OK]
Hint: Use .value for injected refs in Options API templates [OK]
Common Mistakes:
Thinking provider setup needs to return state for provide
Template syntax looks invalid
Provide key seems missing
5. You want to build a compound Tabs component where clicking a tab updates the active tab and content changes accordingly. Which approach correctly implements this pattern in Vue 3?
hard
A. Use local state in each Tab component without sharing activeTab
B. Pass activeTab as prop to each Tab and emit events to Tabs to update state
C. Use provide to share activeTab ref in Tabs, inject in TabList and TabPanels, update activeTab on Tab click
D. Use global event bus to communicate active tab changes between components
The pattern uses provide/inject to share state like activeTab across nested components without prop drilling.
Step 2: Evaluate options for state management
Use provide to share activeTab ref in Tabs, inject in TabList and TabPanels, update activeTab on Tab click correctly uses provide to share activeTab ref and inject in child components, updating activeTab on tab click to reflect changes.
Final Answer:
Use provide to share activeTab ref in Tabs, inject in TabList and TabPanels, update activeTab on Tab click -> Option C
Quick Check:
Compound components share state via provide/inject = D [OK]
Hint: Use provide/inject to share and update active tab state [OK]
Common Mistakes:
Using props and events causing complex prop drilling
Using global event bus which is not recommended
Keeping state local in each tab causing no sync
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.