mirror of https://github.com/vuejs/core.git
fix(hydration): handle consectuvie text nodes during hydration
close #7285 close #7301
This commit is contained in:
parent
ae52a371e5
commit
f44c3b37d4
|
@ -148,6 +148,15 @@ describe('SSR hydration', () => {
|
|||
expect(container.innerHTML).toBe(`<div class="bar">bar</div>`)
|
||||
})
|
||||
|
||||
// #7285
|
||||
test('element with multiple continuous text vnodes', async () => {
|
||||
// should no mismatch warning
|
||||
const { container } = mountWithHydration('<div>fooo</div>', () =>
|
||||
h('div', ['fo', createTextVNode('o'), 'o']),
|
||||
)
|
||||
expect(container.textContent).toBe('fooo')
|
||||
})
|
||||
|
||||
test('element with elements children', async () => {
|
||||
const msg = ref('foo')
|
||||
const fn = vi.fn()
|
||||
|
@ -239,6 +248,17 @@ describe('SSR hydration', () => {
|
|||
)
|
||||
})
|
||||
|
||||
// #7285
|
||||
test('Fragment (multiple continuous text vnodes)', async () => {
|
||||
// should no mismatch warning
|
||||
const { container } = mountWithHydration('<!--[-->fooo<!--]-->', () => [
|
||||
'fo',
|
||||
createTextVNode('o'),
|
||||
'o',
|
||||
])
|
||||
expect(container.textContent).toBe('fooo')
|
||||
})
|
||||
|
||||
test('Teleport', async () => {
|
||||
const msg = ref('foo')
|
||||
const fn = vi.fn()
|
||||
|
|
|
@ -531,7 +531,27 @@ export function createHydrationFunctions(
|
|||
const vnode = optimized
|
||||
? children[i]
|
||||
: (children[i] = normalizeVNode(children[i]))
|
||||
const isText = vnode.type === Text
|
||||
if (node) {
|
||||
if (isText && !optimized) {
|
||||
// #7285 possible consecutive text vnodes from manual render fns or
|
||||
// JSX-compiled fns, but on the client the browser parses only 1 text
|
||||
// node.
|
||||
// look ahead for next possible text vnode
|
||||
let next = children[i + 1]
|
||||
if (next && (next = normalizeVNode(next)).type === Text) {
|
||||
// create an extra TextNode on the client for the next vnode to
|
||||
// adopt
|
||||
insert(
|
||||
createText(
|
||||
(node as Text).data.slice((vnode.children as string).length),
|
||||
),
|
||||
container,
|
||||
nextSibling(node),
|
||||
)
|
||||
;(node as Text).data = vnode.children as string
|
||||
}
|
||||
}
|
||||
node = hydrateNode(
|
||||
node,
|
||||
vnode,
|
||||
|
@ -540,7 +560,7 @@ export function createHydrationFunctions(
|
|||
slotScopeIds,
|
||||
optimized,
|
||||
)
|
||||
} else if (vnode.type === Text && !vnode.children) {
|
||||
} else if (isText && !vnode.children) {
|
||||
// #7215 create a TextNode for empty text node
|
||||
// because server rendered HTML won't contain a text node
|
||||
insert((vnode.el = createText('')), container)
|
||||
|
|
Loading…
Reference in New Issue