Vue.js 3.0 Tutorial
Vue.js 3.0 Component Advanced
Vue.js 3.0 Transitions & Animations
Vue.js 3.0 Reusable & Combinable
Vue.js 3.0 Advanced
Vue.js 3.0 Tools
Vue.js 3.0 Scale
Vue.js 3.0 Accessibility
Vue.js 3.0 Migrating from Vue2
Vue.js 3.0 Contribute Documentation
Vue.js 3.0 API References
Vue.js 3.0 Style Guide
Vue.js provides a provide
and inject
mechanism for dependency injection which can be quite useful in some scenarios. This is typically used to pass values from a parent component down to its descendants without having to pass props through every intermediate component.
This feature can be useful if you have deeply nested components and want to avoid passing props down multiple levels.
Here's a simple example to demonstrate provide
and inject
in Vue 3.0:
In your parent component, you'll want to use the provide
option to specify the data to provide to its descendant components.
<template> <div> <ChildComponent /> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, provide() { return { message: 'Hello from parent' }; } }; </script>
In this example, we're providing a single value message
to any child components.
In any child or grandchild components, you can use the inject
option to access the provided values.
<template> <div> {{ message }} </div> </template> <script> export default { inject: ['message'] }; </script>
In this example, we're injecting message
from the nearest parent component that provides it. This component will now have a message
property that comes from its parent component.
Note: provide
and inject
bindings are NOT reactive by default. If you want to make provide/inject pair reactive, make sure to provide an object and change its properties, or provide a reactive object like a ref or a reactive.
Also, remember to use this feature sparingly. It couples components together and makes the data flow in your application harder to understand since it's not as explicit as props and events. This feature is best used for providing some sort of global state or shared utilities.
Vue 3.0 dependency injection with provide/inject:
Description: provide
and inject
allow a parent component to provide values down the component tree, and child components to inject those values.
Code:
<!-- ParentComponent.vue --> <template> <div> <ChildComponent /> </div> </template> <script> import { ref, provide } from 'vue'; import ChildComponent from './ChildComponent.vue'; export default { setup() { const data = ref('Hello from parent!'); provide('sharedData', data); return {}; }, components: { ChildComponent, }, }; </script>
<!-- ChildComponent.vue --> <template> <div> <p>{{ sharedData }}</p> </div> </template> <script> import { inject } from 'vue'; export default { setup() { const sharedData = inject('sharedData'); return { sharedData }; }, }; </script>
Vue 3.0 provide/inject for global state management:
Description: provide
and inject
can be used to create a global state management system where state is shared among different components.
Code:
<!-- GlobalStateProvider.vue --> <template> <div> <ChildComponentA /> <ChildComponentB /> </div> </template> <script> import { reactive, provide } from 'vue'; import ChildComponentA from './ChildComponentA.vue'; import ChildComponentB from './ChildComponentB.vue'; const globalState = reactive({ message: 'Global State Message', }); provide('globalState', globalState); export default { components: { ChildComponentA, ChildComponentB, }, }; </script>
<!-- ChildComponentA.vue --> <template> <div> <p>{{ globalState.message }}</p> </div> </template> <script> import { inject } from 'vue'; export default { setup() { const globalState = inject('globalState'); return { globalState }; }, }; </script>
Vue 3.0 using provide/inject in composition API:
Description: provide
and inject
can be used in the composition API to share values between composition functions.
Code:
<!-- CompositionAPIProvider.vue --> <template> <div> <ChildComponent /> </div> </template> <script> import { ref, provide, defineComponent } from 'vue'; import useSharedData from './useSharedData'; export default defineComponent({ setup() { const data = ref('Hello from composition API!'); provide('sharedData', data); // Composition API const { sharedData } = useSharedData(); return { sharedData }; }, }); </script>
// useSharedData.js import { inject, ref } from 'vue'; export default function useSharedData() { const sharedData = inject('sharedData', ref('Default Value')); return { sharedData }; }
Vue 3.0 provide/inject and reactivity:
Description: provide
and inject
maintain reactivity. If a reactive object is provided, changes will be reactive in the injected component as well.
Code:
<!-- ReactivityProvider.vue --> <template> <div> <ChildComponent /> </div> </template> <script> import { reactive, provide, defineComponent } from 'vue'; import ChildComponent from './ChildComponent.vue'; export default defineComponent({ setup() { const reactiveData = reactive({ message: 'Reactive Message', }); provide('reactiveData', reactiveData); return {}; }, components: { ChildComponent, }, }); </script>
<!-- ChildComponent.vue --> <template> <div> <p>{{ reactiveData.message }}</p> <button @click="updateMessage">Update Message</button> </div> </template> <script> import { inject, ref } from 'vue'; export default { setup() { const reactiveData = inject('reactiveData'); const updateMessage = () => { reactiveData.message = 'Updated Message'; }; return { reactiveData, updateMessage }; }, }; </script>
Vue 3.0 provide/inject with functional components:
Description: provide
and inject
work seamlessly with functional components, allowing them to access shared values.
Code:
<!-- FunctionalComponentProvider.vue --> <template functional> <ChildComponent /> </template> <script> import { ref, provide } from 'vue'; import ChildComponent from './ChildComponent.vue'; export default { setup() { const data = ref('Hello from functional component!'); provide('sharedData', data); return {}; }, components: { ChildComponent, }, }; </script>
<!-- ChildComponent.vue --> <template functional> <div> <p>{{ inject('sharedData') }}</p> </div> </template>
Vue 3.0 dynamic provide and inject bindings:
Description: provide
and inject
allow dynamic bindings by providing values based on certain conditions or dynamically changing contexts.
Code:
<!-- DynamicBindingProvider.vue --> <template> <div> <ChildComponent v-if="useDynamicBinding" /> </div> </template> <script> import { ref, provide } from 'vue'; import ChildComponent from './ChildComponent.vue'; export default { data() { return { useDynamicBinding: true, }; }, setup() { const dynamicData = ref('Dynamic Binding Data'); provide('dynamicData', dynamicData); return {}; }, components: { ChildComponent, }, }; </script>
<!-- ChildComponent.vue --> <template> <div> <p v-if="dynamicData">{{ dynamicData }}</p> </div> </template> <script> import { inject } from 'vue'; export default { setup() { const dynamicData = inject('dynamicData'); return { dynamicData }; }, }; </script>