Skip to content

Commit

Permalink
fix(ssr): fix hydration for slot with empty text node
Browse files Browse the repository at this point in the history
fix #5728
  • Loading branch information
yyx990803 committed May 19, 2022
1 parent e1bc268 commit 939209c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
21 changes: 20 additions & 1 deletion packages/runtime-core/__tests__/hydration.spec.ts
Expand Up @@ -13,7 +13,8 @@ import {
createTextVNode,
createVNode,
withDirectives,
vModelCheckbox
vModelCheckbox,
renderSlot
} from '@vue/runtime-dom'
import { renderToString, SSRContext } from '@vue/server-renderer'
import { PatchFlags } from '../../shared/src'
Expand Down Expand Up @@ -912,6 +913,24 @@ describe('SSR hydration', () => {
expect((container.firstChild!.firstChild as any)._value).toBe(true)
})

// #5728
test('empty text node in slot', () => {
const Comp = {
render(this: any) {
return renderSlot(this.$slots, 'default', {}, () => [
createTextVNode('')
])
}
}
const { container, vnode } = mountWithHydration('<!--[--><!--]-->', () => h(Comp))
expect(container.childNodes.length).toBe(3)
const text = container.childNodes[1]
expect(text.nodeType).toBe(3)
expect(vnode.el).toBe(container.childNodes[0])
// component => slot fragment => text node
expect((vnode as any).component?.subTree.children[0].el).toBe(text)
})

describe('mismatch handling', () => {
test('text node', () => {
const { container } = mountWithHydration(`foo`, () => 'bar')
Expand Down
13 changes: 12 additions & 1 deletion packages/runtime-core/src/hydration.ts
Expand Up @@ -110,7 +110,18 @@ export function createHydrationFunctions(
switch (type) {
case Text:
if (domType !== DOMNodeTypes.TEXT) {
nextNode = onMismatch()
// #5728 empty text node inside a slot can cause hydration failure
// because the server rendered HTML won't contain a text node
if (vnode.children === '') {
insert(
(vnode.el = document.createTextNode('')),
node.parentElement!,
node
)
nextNode = node
} else {
nextNode = onMismatch()
}
} else {
if ((node as Text).data !== vnode.children) {
hasMismatch = true
Expand Down

0 comments on commit 939209c

Please sign in to comment.