Skip to content

Commit eb22a62

Browse files
authored
fix(ssr): hydration for transition wrapper components with empty slot content (#5995)
fix #5991
1 parent 0cf9ae6 commit eb22a62

File tree

4 files changed

+43
-6
lines changed

4 files changed

+43
-6
lines changed

Diff for: packages/compiler-ssr/__tests__/ssrSlotOutlet.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ describe('ssr: <slot>', () => {
123123
"const { ssrRenderSlotInner: _ssrRenderSlotInner } = require(\\"vue/server-renderer\\")
124124
125125
return function ssrRender(_ctx, _push, _parent, _attrs) {
126-
_ssrRenderSlotInner(_ctx.$slots, \\"default\\", {}, null, _push, _parent)
126+
_ssrRenderSlotInner(_ctx.$slots, \\"default\\", {}, null, _push, _parent, null, true)
127127
}"
128128
`)
129129
})

Diff for: packages/compiler-ssr/src/transforms/ssrTransformSlotOutlet.ts

+4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ export const ssrTransformSlotOutlet: NodeTransform = (node, context) => {
5050
parent.children.filter(c => c.type === NodeTypes.ELEMENT).length === 1
5151
) {
5252
method = SSR_RENDER_SLOT_INNER
53+
if (!(context.scopeId && context.slotted !== false)) {
54+
args.push('null')
55+
}
56+
args.push('true')
5357
}
5458

5559
node.ssrCodegenNode = createCallExpression(context.helper(method), args)

Diff for: packages/server-renderer/__tests__/ssrSlot.spec.ts

+28
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,32 @@ describe('ssr: slot', () => {
113113
`<div><!--[--><!--[--><div>one</div><div>two</div><!--]--><!--]--></div>`
114114
)
115115
})
116+
117+
test('transition slot', async () => {
118+
expect(
119+
await renderToString(
120+
createApp({
121+
components: {
122+
one: {
123+
template: `<transition><slot/></transition>`
124+
}
125+
},
126+
template: `<one><div v-if="false">foo</div></one>`
127+
})
128+
)
129+
).toBe(`<!---->`)
130+
131+
expect(
132+
await renderToString(
133+
createApp({
134+
components: {
135+
one: {
136+
template: `<transition><slot/></transition>`
137+
}
138+
},
139+
template: `<one><div v-if="true">foo</div></one>`
140+
})
141+
)
142+
).toBe(`<div>foo</div>`)
143+
})
116144
})

Diff for: packages/server-renderer/src/helpers/ssrRenderSlot.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ export function ssrRenderSlotInner(
4040
fallbackRenderFn: (() => void) | null,
4141
push: PushFn,
4242
parentComponent: ComponentInternalInstance,
43-
slotScopeId?: string
43+
slotScopeId?: string,
44+
transition?: boolean
4445
) {
4546
const slotFn = slots[slotName]
4647
if (slotFn) {
@@ -61,10 +62,14 @@ export function ssrRenderSlotInner(
6162
// ssr slot.
6263
// check if the slot renders all comments, in which case use the fallback
6364
let isEmptySlot = true
64-
for (let i = 0; i < slotBuffer.length; i++) {
65-
if (!isComment(slotBuffer[i])) {
66-
isEmptySlot = false
67-
break
65+
if (transition) {
66+
isEmptySlot = false
67+
} else {
68+
for (let i = 0; i < slotBuffer.length; i++) {
69+
if (!isComment(slotBuffer[i])) {
70+
isEmptySlot = false
71+
break
72+
}
6873
}
6974
}
7075
if (isEmptySlot) {

0 commit comments

Comments
 (0)