injected ref value is not reactive when updated inside setup of a child component
Version
3.0.0-rc.10
Reproduction link
https://codesandbox.io/s/admiring-snow-4u748?file=/src/Child.vue
Steps to reproduce
Open the reproduction link, in parent component setup we have:
setup() {
const msg = ref("initial");
provide("CONTEXT", { msg });
return {
msg
};
}
and in a child component setup:
setup() {
const ctx = inject("CONTEXT");
// not working (works when wrapped inside onBeforeMount)
ctx.msg.value = "updated";
}
What is expected?
the screen should show: "updated"
What is actually happening?
the screen shows "initial"
It works fine when wrapped inside a lifecycle hook:
onBeforeMount(() => {
ctx.msg.value = "updated";
})
I'm not sure if it's a bug or intentional behavior, but I find it weird since the parent's setup function is executed before the child's.
The usage here is different from the document. 🧐
However, there are times where we need to update the data inside of the component where the data is injected. In this scenario, we recommend providing a method that is responsible for mutating the reactive property.
@Picknight providing a method that updates the ref and calling it in the child's setup makes no difference. https://codesandbox.io/s/elated-meadow-6r04w?file=/src/Child.vue
The deep reason is ac81dcf. @yyx990803 Maybe we should revert it ?
I see this issue is closed but I am not seeing any conclusion on this thread. Am I missing something? I am also looking for solution to my problem.
I'm trying to inject a Boolean value into all components (SFC), which provide/inject seems best suited for. I have Vue 3.1.2.
I tried calling:
const injectedRef = ref(getCurrentState())
app.provide('injectedName', injectedRef)
const injectedComputed = computed(() => injectedRef)
app.provide('injectedName', injectedComputed)
const injectedReactive = reactive({ injectedRef })
app.provide('injectedName', injectedReactive)
As you can see, only the last method worked, but that defeats the purpose of injecting a single true/false variable that can be used directly in components.
This was previously done with:
const reactiveProxy = Vue.observable({ state: getCurrentState() })
Vue.use({
install (vueInstance) {
Object.defineProperty(vueInstance.prototype, '$injectedName', {
get: () => reactiveProxy.state
})
}
})