provide() function signature and usage
The provide() function in Composition API accepts two arguments: the first is the injection key (a string or Symbol), and the second is the provided value. In <script setup>, call provide() at the top level. Outside <script setup>, ensure provide() is called synchronously inside setup(). Example: provide('message', 'hello!')
provide() with reactive values enables reactive connection
When providing reactive state such as refs using provide(), descendant components that inject this value establish a reactive connection to the provider component. The injected ref will not be automatically unwrapped, allowing the injector to retain the reactivity connection.
App-level provide() makes values available to all components
Call app.provide(key, value) on the app instance returned from createApp() to provide data at the app level. App-level provides are available to all components rendered in the app and are especially useful for plugins.
Options API provide option with object syntax
In Options API, use the provide option as an object with key-value pairs. Example: provide: { message: 'hello!' }. For per-instance state, provide must use a function value that returns an object, allowing access to this. Example: provide() { return { message: this.message } }
inject() function signature and basic usage
The inject() function in Composition API takes the injection key as the first argument and returns the injected value. In <script setup>, use: const message = inject('message'). Outside <script setup>, call inject() synchronously inside setup().
inject() resolution from closest parent
When multiple parents provide data with the same key, inject() resolves to the value from the closest parent in the component's parent chain.
inject() default values - string syntax
In Composition API, provide a default value as the second argument to inject(). Example: const value = inject('message', 'default value'). For expensive computations or side effects, use a factory function by passing a third parameter set to true: inject('key', () => new ExpensiveClass(), true)
Options API inject with array and object syntax
In Options API, use the inject option as an array for simple cases: inject: ['message']. For default values or local key aliasing, use object syntax: inject: { localKey: { from: 'injectionKey', default: 'defaultValue' } }. Injections are resolved before the component's own state, so injected properties are accessible in data().
Options API injection aliasing with from property
To inject a property using a different local key in Options API, use the object syntax with the from property: inject: { localMessage: { from: 'message' } }. The component will locate the property provided with key 'message' and expose it as this.localMessage.
Options API injection default values with factory function
In Options API, provide a factory function for default values that should be created per component instance or are expensive to create: inject: { user: { default: () => ({ name: 'John' }) } }
How to provide reactive values so descendants receive updates
In Composition API, provide a ref or reactive object and descendants will reactively receive updates. In Options API, wrap the provided value with computed() function: provide() { return { message: computed(() => this.message) } }. This makes injections reactively linked to the provider.
Recommended pattern for mutable reactive provide/inject
Keep mutations to reactive state inside the provider component whenever possible. If an injector component needs to update data, provide a function responsible for mutating the state from the provider. Provide an object containing both the reactive value and the update function.
Use readonly() to prevent mutations in injector components
Wrap the provided value with readonly() to ensure that data passed through provide cannot be mutated by the injector component. Example: provide('read-only-count', readonly(count))
Symbol injection keys for avoiding collisions
In large applications or when authoring reusable components, use Symbol injection keys instead of strings to avoid potential collisions. Export Symbols in a dedicated file and import them in both provider and injector components.
Providing reactive location with update function example
Example of Composition API provide/inject with reactive state and update function:
<!-- Provider -->
<script setup>
import { provide, ref } from 'vue'
const location = ref('North Pole')
function updateLocation() {
location.value = 'South Pole'
}
provide('location', { location, updateLocation })
</script>
<!-- Injector -->
<script setup>
import { inject } from 'vue'
const { location, updateLocation } = inject('location')
</script>
<template>
<button @click="updateLocation">{{ location }}</button>
</template>