Static Slots optimization combined with component instance re-use can lead to stale slot content never being updated. [EDGE CASE]
Jokcy opened this issue · 4 comments
Version
3.0.4
Reproduction link
https://codesandbox.io/s/demo-for-sfc-slots-issue-n27kc
Steps to reproduce
You can see Hello
never change to World
.
I already find the reason is that SFC compiler add { _: 1 }
to the compiled slots, which in updateSlots
tell Vue there is no need to update instance.slots
. But in this case, it work not correctly.
What is expected?
Hello
and World
switch in 1 second
What is actually happening?
never update
The cause is that the slots for each <A>
are indeed stable and don't need updating, but Vue is re-using the same instance of A
for efficiency when you toggle between the two vnodes.
Not sure we can fix this at the compiler level without de-optimizing the usually justified use-cases of keeping slots stable.
It can be corrected by applying a key
to each instance of A
:
<template>
<B>
<A key="A">Hello</A>
<A key="B">World</A>
</B>
</template>
You could also apply these keys to the vnodes within the render function of B
, depending on your use case.
The cause is that the slots for each
<A>
are indeed stable and don't need updating, but Vue is re-using the same instance ofA
for efficiency when you toggle between the two vnodes.Not sure we can fix this at the compiler level without de-optimizing the usually justified use-cases of keeping slots stable.
It can be corrected by applying a
key
to each instance ofA
:<template> <B> <A key="A">Hello</A> <A key="B">World</A> </B> </template>
You could also apply these keys to the vnodes within the render function of
B
, depending on your use case.
Yeah I know key will help to fix this. But I guess it's better to update this behavior because I spend 2-3 hours to find out why😂, it's really confusing when I face it.
Well I'm saying that at least I personally don't see how, as the problem you are facing here is not detectable by static analysis during compilation.
So the only way I can see would be to never optimize slots in this way, which is too high a price to solve such an edge case, in my opinion.
Maybe a better route would be to document the edge cases one can come across when manually manipulating slots content in render functions.
Yeah, if only edge case like this will face this issue, maybe a doc is enough. Can we find a way to warning when people manually manipulating slots content in render functions?