-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
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
Provided props are not injected into functional components #5837
Comments
It's because that instead of BTW, your fiddle is using vue@1.0.16 😅 |
The lookup algorithm for provide inject is the child looks at itself for provided attributes and then loops up it's vue/src/core/instance/inject.js Line 59 in b182ac4
Couldn't get your fiddle to run, but when i ran https://jsfiddle.net/Austio/vhgztp59/7/ this fiddle the $parent was undefined on the child component when i got to the lookup context. At least that is a start if this is not an issue with rendering into slots and there not being a relationship between the components. |
it looks like the functional component is rendered before slots is resolved |
@Kingwl correct, and that's kind of a technical requirement. |
I remember I raised the point because I was getting crazy about it. At the end, it looked normal to me because functional components are attached to component they're rendered in and therefore when used in a slot, they get attached to the outer component. However, this is not the case with non-functional components: Container injects <!-- rendered in App -->
<container>
<!-- parent is App, mode is undefined -->
<functional></functional>
</container>
<container>
<!-- parent is container, mode is foo -->
<not-functional></not-functional>
</container> edit: @alidcastano I updated the fiddle in your comment since yours wasn't even using Vue 2 |
Haha sorry for using the wrong Vue version in the fiddle, I was too caught up on not being able to configure JSX that I didn't realize. @posva Thanks for fixing my example! -- So the issue here is not that the functional component can't receive the provided properties, it's that the functional component is rendered before the slot? @LinusBorg By "technical requirement" does that mean that there is no workaround or that the behavior is intended? Should a container be created to serve as the
But the above example seems unnecessarily bloated since the essence of the parent component already entailed all the data it needed to provide to the child. But I'm open to discussion; is this what you guys suggest? |
the |
The behaviour is a result of the way functional components work. Consider this set of components: <!-- template of a `parent` component -->
<template>
<Child>
<functional />
</Child>
</template> When you pass a functional component into another component's slot, it has to be rendered befor it is passed to the child, so that that child component can receive the resulting vNodes as the slot content. (*) In the context of my example above, that means that at the moment that the Consequently, the only injections available to the functional component are those that are available in (*): That's just how the current implementaiton of the virtualdom works with functional components. To change that would require quite changing quite a lot of internal mechanics. |
@posva @LinusBorg Got it, thanks for explaining. So due to these requirements, the only way to use provide/inject with functional components is to have the props provided in the I'm sure this constraint will be clarified in the documentation. Please go ahead and close this issue if there isn't anything else that needs to be done or clarified; thanks again! |
Maybe we can find a way to improve functional component in slot |
@Kingwl Thanks for keeping this open. I finally had some time to try to incorporate this into my vue-mobiledoc-editor plugin using the above advice. One problem that I foresee if the component needs to be used from the For example, I have to export the components already registered under the app instance:
Then from my understanding, when the user is using the plugin, it would be like so:
If my implementation is correct then this severely limits the usage of provide/inject with functional components since you're not allowed to individually import and register the components you wish to use. |
I would use full components instead to support the provide/inject |
i'm trying to resolve this |
@Kingwl Were you able to resolve it? |
Are there plans to address this issue in v3? Eg I am trying to abstract a v-for away into a render function but my childs can be functional components (so they are already rendered when entering the render function and I cant clone them). |
Any update? |
Version
2.3.3
Reproduction link
http://jsfiddle.net/p861bj9y/
Steps to reproduce
I created a minimal reproduction of the behavior I am trying to test, the example just needs JSX to work.
What is expected?
The properties passed down from parent should show up in
ctx.injections
.What is actually happening?
Ctx.injections
exists but remains empty. The properties are not being passed down to the functional component context.The text was updated successfully, but these errors were encountered: