-
-
Notifications
You must be signed in to change notification settings - Fork 34
🐛 Fix reactivity for @Provide
#81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Fixes facing-dev#80 This change fixes reactivity when using Provide/Inject. This previously didn't work, because we froze the provided value at `provide()` invocation time by just accessing `sample[name]`. This change automagically wraps any provided values in a `computed()` wrapper, which should update downstream injected values whenever the provider changes. This does two things of note: 1. It uses the Vue.js `computed()` function as demonstrated in the [docs][1] 2. It wraps *any* provided value in `computed()`, including `data`, which removes the need for the extra getter demonstrated in the docs, but is a departure from the "standard" Vue component Options API Note that to use this now requires setting `unwrapInjectedRef: true`. [1]: https://vuejs.org/guide/components/provide-inject.html#working-with-reactivity
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall don't know how fit for purpose this PR is. Not sure I have much time to work on this, but if anyone wants to pick it up as a starting point, go for it.
}, { | ||
global: { | ||
config: { | ||
unwrapInjectedRef: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ruojianll I'm not sure how happy I am with this fix: this config needs to be set to get this to work properly, which isn't great
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://vuejs.org/guide/components/provide-inject.html#working-with-reactivity
In vue 3.3 unwrapInjectedRef=true is a default config.
const slot = obtainSlot(cons.prototype) | ||
const names = slot.obtainMap('provide') | ||
if (!names) return null | ||
names.forEach((value, name) => { | ||
const key = value === null ? name : value | ||
optionBuilder.provide![key] = sample[name] | ||
optionBuilder.provide![key] = computed(() => vueInstance[name]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if we can do anything with optionBuild.computed
instead of relying on the Vue.js computed()
method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are using in a documented vue3 way, that's good.
https://vuejs.org/guide/components/provide-inject.html#working-with-reactivity
Fixes #80
This change fixes reactivity when using Provide/Inject. This previously didn't work, because we froze the provided value at
provide()
invocation time by just accessingsample[name]
.This change automagically wraps any provided values in a
computed()
wrapper, which should update downstream injected values whenever the provider changes.This does two things of note:
computed()
function as demonstrated in the docscomputed()
, includingdata
, which removes the need for the extra getter demonstrated in the docs, but is a departure from the "standard" Vue component Options APINote that to use this now requires setting
unwrapInjectedRef: true
.