Blog>
Snippets

Deeply Nested Component Communication

Use provide/inject to create a deeply nested component communication example, bypassing intermediate components that do not need to interact with the provided state.
// ParentComponent.vue
<template>
  <div>
    <ChildComponent />
  </div>
</template>

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

export default {
  components: { ChildComponent },
  setup() {
    // The data we want to provide to the nested component
    const sharedState = reactive({
      message: 'Hello from Parent!'
    });

    // Provide the state to descendants
    provide('sharedState', sharedState);

    return {};
  }
};
</script>
This parent component provides the shared state to its descendants using the reactive API and the provide function.
// ChildComponent.vue
<template>
  <div>
    <GrandchildComponent />
  </div>
</template>

<script>
import GrandchildComponent from './GrandchildComponent.vue';

export default {
  components: { GrandchildComponent },
  setup() {
    // This intermediate component does not need to interact with the provided state
    return {};
  }
};
</script>
This child component is an intermediate component that does not interact with the provided state and just renders its child.
// GrandchildComponent.vue
<template>
  <div>{{ sharedState.message }}</div>
</template>

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

export default {
  setup() {
    // Inject the shared state in the deeply nested component
    const sharedState = inject('sharedState');

    // The component now has access to the shared state provided by an ancestor
    return { sharedState };
  }
};
</script>
This grandchild component injects the shared state from an ancestor, bypassing the intermediate components.