--- title: Avoid Prop Drilling - Use Provide/Inject for Deep Component Trees impact: MEDIUM impactDescription: Passing props through many layers creates maintenance burden and tight coupling between intermediate components type: best-practice tags: [vue3, props, provide-inject, component-design, state-management, architecture] --- # Avoid Prop Drilling - Use Provide/Inject for Deep Component Trees **Impact: MEDIUM** - Prop drilling occurs when you pass props through multiple component layers just to reach a deeply nested child. This creates tight coupling, makes refactoring difficult, and clutters intermediate components with props they don't use. Vue's provide/inject API allows ancestor components to share data with any descendant, regardless of nesting depth. ## Task Checklist - [ ] Identify when props pass through 2+ intermediate components unchanged - [ ] Use provide/inject for data needed by deeply nested descendants - [ ] Use Pinia for global state shared across unrelated component trees - [ ] Keep props for direct parent-child relationships - [ ] Document provided values at the provider level ## The Problem: Prop Drilling ```vue ``` ```vue ``` ```vue ``` ```vue ``` **Problems:** 1. `MainLayout` and `Sidebar` are cluttered with props they don't use 2. Adding a new shared value requires updating every component in the chain 3. Removing a deeply nested component requires updating all ancestors 4. Difficult to trace where data originates ## Solution: Provide/Inject **Correct - Provider (ancestor):** ```vue ``` **Correct - Intermediate components are now clean:** ```vue ``` ```vue ``` **Correct - Consumer (descendant):** ```vue ``` ```vue ``` ## Best Practices for Provide/Inject ### 1. Use Symbol Keys for Large Apps Avoid string key collisions with symbols: ```js // keys.js export const UserKey = Symbol('user') export const ThemeKey = Symbol('theme') ``` ```vue ``` ```vue ``` ### 2. Provide Default Values Handle cases where no ancestor provides the value: ```vue ``` ### 3. Use Readonly for Data Safety Prevent descendants from mutating provided data: ```vue ``` ### 4. Provide Computed Values for Reactivity ```vue ``` ## When to Use What | Scenario | Solution | |----------|----------| | Direct parent-child | Props | | 1-2 levels deep | Props (drilling is acceptable) | | Deep nesting, same component tree | Provide/Inject | | Unrelated component trees | Pinia (state management) | | Cross-app global state | Pinia | | Plugin configuration | Provide/Inject from plugin install | ## Provide/Inject vs Pinia **Provide/Inject:** - Scoped to component subtree - Great for component library internals - No DevTools support - Ancestor-descendant relationships only **Pinia:** - Global, accessible anywhere - Excellent DevTools integration - Better for application state - Works across unrelated components ## Reference - [Vue.js Provide/Inject](https://vuejs.org/guide/components/provide-inject.html) - [Vue.js - Prop Drilling](https://vuejs.org/guide/components/provide-inject.html#prop-drilling) - [Pinia Documentation](https://pinia.vuejs.org/)