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

Named slot won't render #7817

Labels

Comments

@privatenumber
Copy link
Contributor

Version

2.5.15

Reproduction link

https://jsfiddle.net/hirokiosame/dronjdzm/63/

Steps to reproduce

The jsfiddle link reproduces the issue but it's a pretty intricate combination that reproduces it.

Removing the slot="namedSlot from the div and wrapping it with <template slot="namedSlot">, or removing the usage of the functional component noOp, or disabling reactivity via changing undefined tofalse` on L20 or removing the dependency on L9 will fix the issue.

What is expected?

For the named slot to render. In the case of the reproduction, the "THIS TEXT SHOULD RENDER" text.

What is actually happening?

The named slot is not rendering.

@LinusBorg
Copy link
Member

LinusBorg commented Mar 13, 2018

There's definitely something weird going on.

I added a log to the functional component's render function to inspect the slots that are received:

image

The weird thing is that it's rendered twice (can be explained for itself), but once it receives the slot as "namedSlot", and once as "default", even though the setup is the same.

image

https://jsfiddle.net/dronjdzm/70/

@LinusBorg LinusBorg added the bug label Mar 13, 2018
@gebilaoxiong
Copy link
Member

@LinusBorg
Copy link
Member

@gebilaoxiong I'm not sure that test case applies to the situation we have here, can you elaborate?

The test case you linked to incorporates one functional component passing slot content to another. That's a different situation that ours in this issue.

@gebilaoxiong
Copy link
Member

gebilaoxiong commented Mar 13, 2018

@LinusBorg
I did a simple example:
https://jsfiddle.net/dronjdzm/75/

I think the difference in understanding is on the template of CompB

const CompB = {
  props: ['state'],
  components: {
    CompA
  },
  template: `
    <div>
      <comp-a>
        <slot name="slotA"></slot>
        {{ state.prop }}
      </comp-a>  
    </div>
  `
};

When CompB is rendered, it generates a structure similar to the follow vnode:

<div>
  <comp-a>
     <span slot="slotA">
       THIS TEXT SHOULD RENDER
     </span>
    {{ state.prop }}
  </comp-a>  
</div>

When CompA is rendered, the slots is:

{
  slotA:  [Vnode], // span element
  default: [Vnode] // state.prop
}

so I think not render it is right.

@gebilaoxiong
Copy link
Member

gebilaoxiong commented Mar 13, 2018

Perhaps the slot="slotA" on the span should be deleted when the CompB is rendered.

Maybe you're right

f2009 pushed a commit to f2009/vue that referenced this issue Jan 25, 2019
This is a subtle edge case caused when a stateful component triggers
a self re-render, which reuses cached slot nodes. The cached slot
nodes, if returned from a functional render fn, gets the fnContext
property which causes subsequent slot resolving to not function
properly. To fix this, nodes returned from functional components
need to be cloned before getting assigned fnContext.

fix vuejs#7817
aJean pushed a commit to aJean/vue that referenced this issue Aug 19, 2020
This is a subtle edge case caused when a stateful component triggers
a self re-render, which reuses cached slot nodes. The cached slot
nodes, if returned from a functional render fn, gets the fnContext
property which causes subsequent slot resolving to not function
properly. To fix this, nodes returned from functional components
need to be cloned before getting assigned fnContext.

fix vuejs#7817
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment