diff --git a/packages/runtime-vapor/__tests__/hydration.spec.ts b/packages/runtime-vapor/__tests__/hydration.spec.ts index 999caf97c..1eb43e0bb 100644 --- a/packages/runtime-vapor/__tests__/hydration.spec.ts +++ b/packages/runtime-vapor/__tests__/hydration.spec.ts @@ -1746,8 +1746,8 @@ describe('Vapor Mode hydration', () => { a b - c - " + c + " `, ) @@ -1759,8 +1759,8 @@ describe('Vapor Mode hydration', () => { a b - cd - " + c + d" `, ) }) @@ -1801,6 +1801,57 @@ describe('Vapor Mode hydration', () => { `, ) }) + + test('on component with non-hydration node', async () => { + const data = ref({ show: true, msg: 'foo' }) + const { container } = await testHydration( + ``, + { + Child: ``, + }, + data, + ) + expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( + ` + "
+
foo
non-hydration node
foo
non-hydration node
" + `, + ) + + data.value.msg = 'bar' + await nextTick() + expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot( + ` + "
+
bar
non-hydration node
bar
non-hydration node
" + `, + ) + + data.value.show = false + await nextTick() + expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(` + "
+
non-hydration node
non-hydration node
" + `) + + data.value.show = true + await nextTick() + expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(` + "
+
bar
non-hydration node
bar
non-hydration node
" + `) + }) }) describe('slots', () => { diff --git a/packages/runtime-vapor/src/apiCreateFor.ts b/packages/runtime-vapor/src/apiCreateFor.ts index 4e88afe8f..7fdc31214 100644 --- a/packages/runtime-vapor/src/apiCreateFor.ts +++ b/packages/runtime-vapor/src/apiCreateFor.ts @@ -30,8 +30,9 @@ import { isHydrating, locateFragmentEndAnchor, locateHydrationNode, + setCurrentHydrationNode, } from './dom/hydration' -import { ForFragment, VaporFragment } from './fragment' +import { ForFragment, VaporFragment, findLastChild } from './fragment' import { insertionAnchor, insertionParent, @@ -130,10 +131,20 @@ export const createFor = ( if (!isMounted) { isMounted = true for (let i = 0; i < newLength; i++) { + if (isHydrating && isComponent && i > 0) { + setCurrentHydrationNode( + findLastChild(newBlocks[i - 1].nodes)!.nextSibling, + ) + } mount(source, i) } if (isHydrating) { + if (isComponent) { + setCurrentHydrationNode( + findLastChild(newBlocks[newLength - 1].nodes)!.nextSibling, + ) + } parentAnchor = locateFragmentEndAnchor()! if (__DEV__) { if (!parentAnchor) { diff --git a/packages/runtime-vapor/src/block.ts b/packages/runtime-vapor/src/block.ts index aeac078ae..16e18e9aa 100644 --- a/packages/runtime-vapor/src/block.ts +++ b/packages/runtime-vapor/src/block.ts @@ -157,7 +157,7 @@ export function normalizeAnchor(node: Block): Node | undefined { if (node && node instanceof Node) { return node } else if (isArray(node)) { - return normalizeAnchor(node[0]) + return normalizeAnchor(node[node.length - 1]) } else if (isVaporComponent(node)) { return normalizeAnchor(node.block!) } else {