Skip to content

🐛 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

Merged
merged 1 commit into from
Oct 16, 2023

Conversation

alecgibson
Copy link
Contributor

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 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
  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.

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
Copy link
Contributor Author

@alecgibson alecgibson left a 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,
Copy link
Contributor Author

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

Copy link
Contributor

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])
Copy link
Contributor Author

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?

Copy link
Contributor

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

@ruojianll ruojianll marked this pull request as ready for review October 16, 2023 22:46
@ruojianll ruojianll merged commit ad701ee into facing-dev:master Oct 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

如何实现 Provide 响应式数据提供
2 participants