From eb22a62798d845a8756b0a73b68afdd874feda59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E5=88=98=28liulinboyi=29?= <814921718@qq.com> Date: Mon, 6 Jun 2022 16:24:40 +0800 Subject: [PATCH] fix(ssr): hydration for transition wrapper components with empty slot content (#5995) fix #5991 --- .../__tests__/ssrSlotOutlet.spec.ts | 2 +- .../src/transforms/ssrTransformSlotOutlet.ts | 4 +++ .../server-renderer/__tests__/ssrSlot.spec.ts | 28 +++++++++++++++++++ .../src/helpers/ssrRenderSlot.ts | 15 ++++++---- 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/packages/compiler-ssr/__tests__/ssrSlotOutlet.spec.ts b/packages/compiler-ssr/__tests__/ssrSlotOutlet.spec.ts index 695cfdf7f13..21fbe649c4a 100644 --- a/packages/compiler-ssr/__tests__/ssrSlotOutlet.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrSlotOutlet.spec.ts @@ -123,7 +123,7 @@ describe('ssr: ', () => { "const { ssrRenderSlotInner: _ssrRenderSlotInner } = require(\\"vue/server-renderer\\") return function ssrRender(_ctx, _push, _parent, _attrs) { - _ssrRenderSlotInner(_ctx.$slots, \\"default\\", {}, null, _push, _parent) + _ssrRenderSlotInner(_ctx.$slots, \\"default\\", {}, null, _push, _parent, null, true) }" `) }) diff --git a/packages/compiler-ssr/src/transforms/ssrTransformSlotOutlet.ts b/packages/compiler-ssr/src/transforms/ssrTransformSlotOutlet.ts index 3486f355102..c4bbb6ff620 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformSlotOutlet.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformSlotOutlet.ts @@ -50,6 +50,10 @@ export const ssrTransformSlotOutlet: NodeTransform = (node, context) => { parent.children.filter(c => c.type === NodeTypes.ELEMENT).length === 1 ) { method = SSR_RENDER_SLOT_INNER + if (!(context.scopeId && context.slotted !== false)) { + args.push('null') + } + args.push('true') } node.ssrCodegenNode = createCallExpression(context.helper(method), args) diff --git a/packages/server-renderer/__tests__/ssrSlot.spec.ts b/packages/server-renderer/__tests__/ssrSlot.spec.ts index baf8f227806..9b93a55c0f0 100644 --- a/packages/server-renderer/__tests__/ssrSlot.spec.ts +++ b/packages/server-renderer/__tests__/ssrSlot.spec.ts @@ -113,4 +113,32 @@ describe('ssr: slot', () => { `
one
two
` ) }) + + test('transition slot', async () => { + expect( + await renderToString( + createApp({ + components: { + one: { + template: `` + } + }, + template: `
foo
` + }) + ) + ).toBe(``) + + expect( + await renderToString( + createApp({ + components: { + one: { + template: `` + } + }, + template: `
foo
` + }) + ) + ).toBe(`
foo
`) + }) }) diff --git a/packages/server-renderer/src/helpers/ssrRenderSlot.ts b/packages/server-renderer/src/helpers/ssrRenderSlot.ts index 8f746ec1e47..fbe7266b2a1 100644 --- a/packages/server-renderer/src/helpers/ssrRenderSlot.ts +++ b/packages/server-renderer/src/helpers/ssrRenderSlot.ts @@ -40,7 +40,8 @@ export function ssrRenderSlotInner( fallbackRenderFn: (() => void) | null, push: PushFn, parentComponent: ComponentInternalInstance, - slotScopeId?: string + slotScopeId?: string, + transition?: boolean ) { const slotFn = slots[slotName] if (slotFn) { @@ -61,10 +62,14 @@ export function ssrRenderSlotInner( // ssr slot. // check if the slot renders all comments, in which case use the fallback let isEmptySlot = true - for (let i = 0; i < slotBuffer.length; i++) { - if (!isComment(slotBuffer[i])) { - isEmptySlot = false - break + if (transition) { + isEmptySlot = false + } else { + for (let i = 0; i < slotBuffer.length; i++) { + if (!isComment(slotBuffer[i])) { + isEmptySlot = false + break + } } } if (isEmptySlot) {