fix(ssr): avoid rendering transition-group slot content as a fragment (#9961)

close #9933
This commit is contained in:
edison 2024-01-03 17:43:08 +08:00 committed by GitHub
parent 25f212d8a7
commit 0160264d67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 1 deletions

View File

@ -137,4 +137,20 @@ describe('ssr: slot', () => {
),
).toBe(`<div>foo</div>`)
})
// #9933
test('transition-group slot', async () => {
expect(
await renderToString(
createApp({
components: {
one: {
template: `<TransitionGroup tag="div"><slot/></TransitionGroup>`,
},
},
template: `<one><p v-for="i in 2">{{i}}</p></one>`,
}),
),
).toBe(`<div><p>1</p><p>2</p></div>`)
})
})

View File

@ -82,7 +82,23 @@ export function ssrRenderSlotInner(
fallbackRenderFn()
}
} else {
for (let i = 0; i < slotBuffer.length; i++) {
// #9933
// Although we handle Transition/TransitionGroup in the transform stage
// without rendering it as a fragment, the content passed into the slot
// may still be a fragment.
// Therefore, here we need to avoid rendering it as a fragment again.
let start = 0
let end = slotBuffer.length
if (
transition &&
slotBuffer[0] === '<!--[-->' &&
slotBuffer[end - 1] === '<!--]-->'
) {
start++
end--
}
for (let i = start; i < end; i++) {
push(slotBuffer[i])
}
}