vuejs-provide-inject

Provide and Inject in Vue.js

  • 3 min

In Vue.js, provide and inject are two functions that allow you to share data between components in a deep hierarchy.

We have already seen that the usual way to pass data and variables from a parent component to a child component is to use props.

However, if there are multiple levels of nested components, passing it from one component to another, and to another, and to another can become cumbersome.

This problem is known as prop drilling, and it ends up becoming a little syntax pain.

To improve this, Vue provides provide and inject as an alternative to using props to pass data between components without manually passing through each level.

What are provide and inject?

The keywords provide and inject are part of a mechanism that allows us to share data between components.

  • provide: Used in a parent component to provide data or methods that will be available to all its descendant components.
  • inject: Used in a child component to inject the data or methods provided by an ancestor component.

Let’s see it with an example.

<template>
  <div>
    <ChildComponent />
  </div>
</template>

<script setup>
import { provide } from 'vue';
import ChildComponent from './ChildComponent.vue';

const message = 'Hello from the parent component';
provide('message', message); // Provides the value 'message'
</script>
<template>
  <div>
    <p>Received message: {{ injectedMessage }}</p>
  </div>
</template>

<script setup>
import { inject } from 'vue';

const injectedMessage = inject('message'); // Injects the value 'message'
</script>

In this example:

  • The parent component (ParentComponent) provides a value (message) using provide.
  • The child component (ChildComponent) injects the value using inject and displays it in its template.

Default Values in inject

<template>
  <div>
    <p>Received message: {{ injectedMessage }}</p>
  </div>
</template>

<script setup>
import { inject } from 'vue';

const injectedMessage = inject('message', 'Default value'); // Default value
</script>

In this example:

  • If the message value is not available, the default value 'Default value' is used.

Providing and Injecting Reactive Data

The data provided with provide can be reactive, meaning changes in the data will automatically reflect in the components that inject them.

<template>
  <div>
    <ChildComponent />
    <button @click="changeMessage">Change message</button>
  </div>
</template>

<script setup>
import { provide, ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const message = ref('Hello from the parent component');
provide('message', message); // Provides the reactive value 'message'

function changeMessage() {
  message.value = 'Message changed!';
}
</script>
<template>
  <div>
    <p>Received message: {{ injectedMessage }}</p>
  </div>
</template>

<script setup>
import { inject } from 'vue';

const injectedMessage = inject('message'); // Injects the reactive value 'message'
</script>

In this example:

  • The parent component provides a reactive value (message) using provide.
  • The child component injects the reactive value and displays it in its template.
  • When the button in the parent component changes the message, the child component updates automatically.

Providing and Injecting Methods

In addition to data, you can also provide and inject methods. This is useful for sharing functionalities between components.

<template>
  <div>
    <ChildComponent />
  </div>
</template>

<script setup>
import { provide } from 'vue';
import ChildComponent from './ChildComponent.vue';

function showAlert() {
  alert('This is a method provided by the parent component!');
}

provide('showAlert', showAlert); // Provides the method 'showAlert'
</script>
<template>
  <div>
    <button @click="injectedShowAlert">Show alert</button>
  </div>
</template>

<script setup>
import { inject } from 'vue';

const injectedShowAlert = inject('showAlert'); // Injects the method 'showAlert'
</script>

In this example:

  • The parent component provides a method (showAlert) using provide.
  • The child component injects the method and uses it in a button.