YouTip LogoYouTip

Vue3 Api Inject

## Vue3 inject() Function The `inject()` function is a core Composition API in Vue 3. It allows a child or deeply nested descendant component to retrieve dependencies provided by an ancestor component via the `provide()` function. This mechanism is commonly referred to as **Dependency Injection**. It is designed to facilitate cross-level component communication, especially when dealing with deeply nested component trees where passing props down through every level (prop drilling) becomes impractical. --- ### Basic Syntax ```javascript import { inject } from 'vue'; const value = inject(key, defaultValue, treatDefaultAsFactory); ``` #### Parameters: * **`key`**: A string or a `Symbol` representing the unique identifier of the dependency you want to retrieve. * **`defaultValue`** *(Optional)*: The fallback value returned if the specified key is not provided by any ancestor component. * **`treatDefaultAsFactory`** *(Optional)*: A boolean indicating whether the `defaultValue` should be treated as a factory function. This is useful when the default value is expensive to compute or is a mutable object/array that should be instantiated per component instance. --- ## Common Use Cases The `provide()` and `inject()` APIs are typically used together in the following scenarios: 1. **Deeply Nested Component Communication**: When components are nested several layers deep, using `provide()` and `inject()` avoids the tedious process of passing props through intermediate components that do not need them. 2. **Lightweight State Management**: For small-to-medium applications, `provide()` and `inject()` can serve as a lightweight alternative to dedicated state management libraries like Pinia or Vuex. 3. **Plugin and Library Development**: When developing Vue plugins or component libraries, `inject()` is a powerful tool to expose global configurations, services, or instances to consumer components. --- ## Code Examples ### 1. Basic Usage (Composition API with ` ``` #### Descendant Component (Injecting Data) The deeply nested child component uses `inject()` to resolve and consume the provided data. ```vue ``` --- ### 2. Advanced Usage: Using Factory Functions for Default Values If the default value is a complex object or needs to be computed dynamically, you can pass a factory function as the second argument and set the third argument to `true`. ```javascript import { inject } from 'vue'; // The factory function will only be executed if 'config' is not provided. const config = inject('config', () => ({ port: 8080, host: 'localhost' }), true); ``` --- ## Best Practices and Considerations ### 1. Maintaining Reactivity If you pass a reactive reference (like a `ref` or `reactive` object) to `provide()`, the injected value in the child component remains fully reactive. Any changes made to the state in the parent component will automatically trigger updates in the child component. ### 2. Mutating Reactive Data (One-Way Data Flow) To adhere to Vue's one-way data flow principle, it is recommended to **mutate reactive state only inside the component where it was defined**. If a child component needs to update the injected data, you should provide a mutation function alongside the state: ```javascript // Parent Component const theme = ref('light'); const toggleTheme = () => { theme.value = theme.value === 'light' ? 'dark' : 'light'; }; provide('themeContext', { theme, toggleTheme // Pass the modifier function to the child }); ``` If you want to ensure that the injected data cannot be mutated by the child component, wrap the provided value with `readonly()`: ```javascript import { provide, readonly, ref } from 'vue'; const count = ref(0); provide('count', readonly(count)); // Child can read but cannot modify directly ``` ### 3. Using Symbols for Keys In large-scale applications or when writing reusable plugins, using string keys for `provide` and `inject` can lead to naming collisions. To prevent this, use a `Symbol` as the injection key: ```javascript // keys.js export const MyInjectionKey = Symbol('MyInjectionKey'); // Parent.vue import { MyInjectionKey } from './keys.js'; provide(MyInjectionKey, 'secureData'); // Child.vue import { MyInjectionKey } from './keys.js'; const data = inject(MyInjectionKey); ``` ### 4. Always Provide a Default Value If an injected key is not found in the ancestor chain, Vue will throw a runtime warning. To prevent this and make your components more resilient, always specify a sensible default value as the second argument to `inject()`.
← Vue3 Api ExtendsVue3 Api Slot β†’