Skip to content
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

$parent doesn't skip transition components #2437

Closed
LinusBorg opened this issue Oct 19, 2020 · 6 comments
Closed

$parent doesn't skip transition components #2437

LinusBorg opened this issue Oct 19, 2020 · 6 comments
Assignees
Labels
🐞 bug Something isn't working scope: transition

Comments

@LinusBorg
Copy link
Member

Version

3.0.1

Reproduction link

https://codesandbox.io/s/clever-paper-9zw1d?file=/src/components/HelloWorld.vue

Steps to reproduce

  1. Open the production link
  2. Watch the console

What is expected?

console output:

plain App 
in Transition App 
in Keep-Alive App 
in Teleport App 

What is actually happening?

console output

plain App 
in Transition BaseTransition 
in Keep-Alive App 
in Teleport App 

In Vue 2, the transition component was "abstract" and $parent skipped it, so components could reach the "real" parent component.

Now, the parent of a component nested in an transition is a BaseTransitioninstance, and, adding to the problem, this component doesn't have a public proxy with a $parent property, so developers can't even manually skip it by calling this.$parent.$parent

@LinusBorg LinusBorg added 🐞 bug Something isn't working scope: transition labels Oct 19, 2020
@yyx990803
Copy link
Member

yyx990803 commented Oct 19, 2020

In v3 there really isn't the concept of "abstract" components (i.e. ones that are omitted from parent chains) anymore, so this is expected behavior (and yes, technically a breaking change from v2, but the idea is that the usage of $parent should be strongly discouraged in v3 with Composition APIs)

I think the actual issue here is that Transition is a functional HOC which doesn't even have a public instance proxy. Or more generally, any presence of a functional component in the parent chain would prevent the child from traversing all the way to the root via $parent.

Note: In v2, functional components do not show up in the parent chain at all. To fix this we should probably make the $parent getter ignore functional parents (like in v2).

@LinusBorg
Copy link
Member Author

LinusBorg commented Oct 19, 2020

I think the actual issue here is that Transition is a functional HOC which doesn't even have a public instance proxy. Or more generally, any presence of a functional component in the parent chain would prevent the child from traversing all the way to the root via $parent.

I'm not sure that's exactly the issue here. Functional components don't have instances, they are only represented by vnodes. instance.parent would never point to a vnode, it always points to a ComponentInternalInstance (at least that's what the types say).

The parent that is returned by instance.parent here is { type: {name: 'Basecomponent' }, ... }, or in other words, $parent doesn't seem to point to the functional component from runtime-dom, but rather the the BaseTransition component from runtime-core, which the runtime-dom functional component wraps.

From my tests, doing this:

if (parent.type.name == 'BaseTransition') {
  parent = parent.parent
}

would give me the parent component that contains the <transition> transition, which is the component we want. Of course that implementation might be a bit naive, but that's the gist of it.

@yyx990803
Copy link
Member

yyx990803 commented Oct 19, 2020

You are using $parent which is a special getter on the public proxy, not instance.parent on the internal instance.

The internal .parent chain works (and includes functional components), but there is no equivalent in v2. The problematic part is the .$parent chain on the public instance which currently has a different behavior in v3.

@LinusBorg
Copy link
Member Author

I know. $parent is using instance.parent.proxy.

But that fails when a BaseTransition is the parent.

@yyx990803
Copy link
Member

That's why I'm suggesting the fix is going further up the parent chain when $parent encounters a functional component (i.e. an internal instance whose proxy is null).

@LinusBorg
Copy link
Member Author

Got it.

@LinusBorg LinusBorg self-assigned this Oct 22, 2020
@github-actions github-actions bot locked and limited conversation to collaborators Oct 31, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🐞 bug Something isn't working scope: transition
Projects
None yet
Development

No branches or pull requests

2 participants