fix(ssr): fix hydration mismatch when entire multi-root template is stringified

fix #6637
This commit is contained in:
Evan You 2022-09-28 09:33:17 +08:00
parent 03820193a8
commit 9698dd3cf1
2 changed files with 18 additions and 5 deletions

View File

@ -982,6 +982,14 @@ describe('SSR hydration', () => {
expect((container as any)._vnode).toBe(null) expect((container as any)._vnode).toBe(null)
}) })
// #6637
test('stringified root fragment', () => {
mountWithHydration(`<!--[--><div></div><!--]-->`, () =>
createStaticVNode(`<div></div>`, 1)
)
expect(`mismatch`).not.toHaveBeenWarned()
})
describe('mismatch handling', () => { describe('mismatch handling', () => {
test('text node', () => { test('text node', () => {
const { container } = mountWithHydration(`foo`, () => 'bar') const { container } = mountWithHydration(`foo`, () => 'bar')

View File

@ -108,7 +108,7 @@ export function createHydrationFunctions(
) )
const { type, ref, shapeFlag, patchFlag } = vnode const { type, ref, shapeFlag, patchFlag } = vnode
const domType = node.nodeType let domType = node.nodeType
vnode.el = node vnode.el = node
if (patchFlag === PatchFlags.BAIL) { if (patchFlag === PatchFlags.BAIL) {
@ -150,9 +150,12 @@ export function createHydrationFunctions(
} }
break break
case Static: case Static:
if (domType !== DOMNodeTypes.ELEMENT && domType !== DOMNodeTypes.TEXT) { if (isFragmentStart) {
nextNode = onMismatch() // entire template is static but SSRed as a fragment
} else { node = nextSibling(node)!
domType = node.nodeType
}
if (domType === DOMNodeTypes.ELEMENT || domType === DOMNodeTypes.TEXT) {
// determine anchor, adopt content // determine anchor, adopt content
nextNode = node nextNode = node
// if the static vnode has its content stripped during build, // if the static vnode has its content stripped during build,
@ -169,7 +172,9 @@ export function createHydrationFunctions(
} }
nextNode = nextSibling(nextNode)! nextNode = nextSibling(nextNode)!
} }
return nextNode return isFragmentStart ? nextSibling(nextNode) : nextNode
} else {
onMismatch()
} }
break break
case Fragment: case Fragment: