From e8ddf8608021785c7b1b6f4211c633b40f26ddfc Mon Sep 17 00:00:00 2001 From: HcySunYang Date: Wed, 26 May 2021 23:52:03 +0800 Subject: [PATCH] fix(runtime-core): properly check forwarded slots type (#3781) fix #3779 --- .../__tests__/rendererOptimizedMode.spec.ts | 50 +++++++++++++++++++ packages/runtime-core/src/vnode.ts | 6 +-- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts b/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts index 8c28d881..ef4f3ef8 100644 --- a/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts +++ b/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts @@ -734,4 +734,54 @@ describe('renderer: optimized mode', () => { await nextTick() expect(inner(root)).toBe('

1

') }) + + // #3779 + test('treat slots manually written by the user as dynamic', async () => { + const Middle = { + setup(props: any, { slots }: any) { + return slots.default! + } + } + + const Comp = { + setup(props: any, { slots }: any) { + return () => { + return ( + openBlock(), + createBlock('div', null, [ + createVNode(Middle, null, { + default: withCtx( + () => [ + createVNode('div', null, [renderSlot(slots, 'default')]) + ], + undefined + ), + _: 3 /* FORWARDED */ + }) + ]) + ) + } + } + } + + const loading = ref(false) + const app = createApp({ + setup() { + return () => { + // important: write the slot content here + const content = h('span', loading.value ? 'loading' : 'loaded') + return h(Comp, null, { + default: () => content + }) + } + } + }) + + app.mount(root) + expect(inner(root)).toBe('
loaded
') + + loading.value = true + await nextTick() + expect(inner(root)).toBe('
loading
') + }) }) diff --git a/packages/runtime-core/src/vnode.ts b/packages/runtime-core/src/vnode.ts index 7e5976e2..99adae44 100644 --- a/packages/runtime-core/src/vnode.ts +++ b/packages/runtime-core/src/vnode.ts @@ -651,12 +651,12 @@ export function normalizeChildren(vnode: VNode, children: unknown) { // a child component receives forwarded slots from the parent. // its slot type is determined by its parent's slot type. if ( - currentRenderingInstance.vnode.patchFlag & PatchFlags.DYNAMIC_SLOTS + (currentRenderingInstance.slots as RawSlots)._ === SlotFlags.STABLE ) { + ;(children as RawSlots)._ = SlotFlags.STABLE + } else { ;(children as RawSlots)._ = SlotFlags.DYNAMIC vnode.patchFlag |= PatchFlags.DYNAMIC_SLOTS - } else { - ;(children as RawSlots)._ = SlotFlags.STABLE } } }