From: HcySunYang Date: Wed, 26 May 2021 15:52:03 +0000 (+0800) Subject: fix(runtime-core): properly check forwarded slots type (#3781) X-Git-Tag: v3.1.0-beta.5~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e8ddf8608021785c7b1b6f4211c633b40f26ddfc;p=thirdparty%2Fvuejs%2Fcore.git fix(runtime-core): properly check forwarded slots type (#3781) fix #3779 --- diff --git a/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts b/packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts index 8c28d88102..ef4f3ef835 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 7e5976e2f7..99adae44c0 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 } } }