Static Slots optimization combined with component instance re-use can lead to stale slot content never being updated. [EDGE CASE]
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.