Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vue 3.5+ Composition API reference with progressive sub-file loading for components, composables, reactivity, and testing.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/provide-inject.md
1---2name: Provide / Inject3description: Pass data through component tree without prop drilling4---56# Provide / Inject78Provide data from ancestor components to any descendant, avoiding prop drilling.910## Basic Usage1112```vue13<!-- Provider.vue -->14<script setup lang="ts">15import { provide, ref } from 'vue'1617const message = ref('hello')18provide('message', message)19</script>20```2122```vue23<!-- DeepChild.vue (any level deep) -->24<script setup lang="ts">25import { inject } from 'vue'2627const message = inject('message')28</script>29```3031## Typing with InjectionKey3233Use `InjectionKey` for type safety between provider and injector:3435```ts36// keys.ts37import type { InjectionKey, Ref } from 'vue'3839export const messageKey = Symbol() as InjectionKey<Ref<string>>40export const countKey = Symbol() as InjectionKey<number>41```4243```vue44<!-- Provider.vue -->45<script setup lang="ts">46import { provide, ref } from 'vue'47import { messageKey } from './keys'4849const message = ref('hello')50provide(messageKey, message)51</script>52```5354```vue55<!-- Injector.vue -->56<script setup lang="ts">57import { inject } from 'vue'58import { messageKey } from './keys'5960const message = inject(messageKey) // Ref<string> | undefined61</script>62```6364## Default Values6566```ts67// Simple default68const value = inject('message', 'default value')6970// Factory function (for expensive defaults)71const value = inject('key', () => new ExpensiveClass(), true)72// ^ treat as factory73```7475## App-Level Provide7677Available to all components:7879```ts80// main.ts81import { createApp } from 'vue'8283const app = createApp(App)84app.provide('globalConfig', { theme: 'dark' })85```8687## Reactive Provide/Inject8889Provide reactive values for automatic updates:9091```vue92<!-- Provider.vue -->93<script setup lang="ts">94import { provide, ref } from 'vue'9596const count = ref(0)97provide('count', count)98</script>99```100101The injected value maintains reactivity connection.102103## Mutations Best Practice104105Keep mutations in the provider, expose update functions:106107```vue108<!-- Provider.vue -->109<script setup lang="ts">110import { provide, ref, readonly } from 'vue'111112const location = ref('North Pole')113114function updateLocation(newLocation: string) {115location.value = newLocation116}117118provide('location', {119location: readonly(location), // Prevent direct mutation120updateLocation121})122</script>123```124125```vue126<!-- Injector.vue -->127<script setup lang="ts">128import { inject } from 'vue'129130const { location, updateLocation } = inject('location')!131</script>132133<template>134<button @click="updateLocation('South Pole')">135{{ location }}136</button>137</template>138```139140## Using Symbol Keys141142Recommended for libraries and large apps to avoid collisions:143144```ts145// keys.ts146export const myKey = Symbol('myKey')147148// provider149provide(myKey, value)150151// injector152inject(myKey)153```154155## Type Helpers156157```ts158// String key with explicit type159const foo = inject<string>('foo')160// ^? string | undefined161162// With default (removes undefined)163const foo = inject<string>('foo', 'default')164// ^? string165166// Force non-undefined (use when certain it's provided)167const foo = inject('foo') as string168```169170<!--171Source references:172- https://vuejs.org/guide/components/provide-inject.html173- https://vuejs.org/guide/typescript/composition-api.html#typing-provide-inject174-->175