'How to make provide/inject reactive in Vue 3 to avoid props drilling?

I have a root component that has a lot of descendants. In order to avoid props drilling, I want to use provide/inject.

In the root component in the setup function, I use provide. In the child component in the setup function, I get the value via inject.

Then the child component might emit an event, that forces the root component to reload data that it provides to the child components.

However, the data in the child component is not changed.

Previous answers that I found usually were related to Vue 2, and I'm struggling with Vue 3 composition API.

I tried to use watch/watchEffect, and "re-provide" the data, but it didn't work (and I'm not sure if it's a good solution).

Sample code: https://codesandbox.io/s/mystifying-diffie-e3eqyq



Solution 1:[1]

I don't want to be that guy, but read the docs! Anyway:

App.vue

 setup() {
    let randomNumber = ref(Math.random());

    function updateRandomNumber() {
      randomNumber.value = Math.random()
    }
    // This should be an AJAX call to re-configurate all the children
    // components. All of them needs some kind of config.
    // How to "re-provide" the data after a child component asked this?


    provide("randomNumber", {
      randomNumber,
      updateRandomNumber
    });
  },

ChildComponent.vue

<template>
  <div>Child component</div>
  <button @click="updateRandomNumber">Ask root component for re-init</button>
  <div>Injected data: {{ randomNumber }}</div>
</template>

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

export default {
  setup() {
    // How to "re-inject" the data from parent?
    const {randomNumber, updateRandomNumber} = inject("randomNumber");

    return {
      randomNumber,
      updateRandomNumber
    };
  },
};
</script>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Fabian Lehmann