diff --git a/packages/compiler-vapor/src/transforms/transformChildren.ts b/packages/compiler-vapor/src/transforms/transformChildren.ts index 790cd9d6f..da47438c2 100644 --- a/packages/compiler-vapor/src/transforms/transformChildren.ts +++ b/packages/compiler-vapor/src/transforms/transformChildren.ts @@ -70,10 +70,23 @@ function processDynamicChildren(context: TransformContext) { if (!(child.flags & DynamicFlag.NON_TEMPLATE)) { if (prevDynamics.length) { if (hasStaticTemplate) { - context.childrenTemplate[index - prevDynamics.length] = `` - prevDynamics[0].flags -= DynamicFlag.NON_TEMPLATE - const anchor = (prevDynamics[0].anchor = context.increaseId()) - registerInsertion(prevDynamics, context, anchor) + // each dynamic child gets its own placeholder node. + // this makes it easier to locate the corresponding node during hydration. + for (let i = 0; i < prevDynamics.length; i++) { + const idx = index - prevDynamics.length + i + context.childrenTemplate[idx] = `` + const dynamicChild = prevDynamics[i] + dynamicChild.flags -= DynamicFlag.NON_TEMPLATE + const anchor = (dynamicChild.anchor = context.increaseId()) + if ( + dynamicChild.operation && + isBlockOperation(dynamicChild.operation) + ) { + // block types + dynamicChild.operation.parent = context.reference() + dynamicChild.operation.anchor = anchor + } + } } else { registerInsertion(prevDynamics, context, -1 /* prepend */) } diff --git a/packages/runtime-vapor/__tests__/hydration.spec.ts b/packages/runtime-vapor/__tests__/hydration.spec.ts index 27ef427a1..246d8c9b9 100644 --- a/packages/runtime-vapor/__tests__/hydration.spec.ts +++ b/packages/runtime-vapor/__tests__/hydration.spec.ts @@ -317,7 +317,7 @@ describe('Vapor Mode hydration', () => { ) }) - test.todo('mixed component and text with anchor insertion', async () => { + test('mixed component and text with anchor insertion', async () => { const { container, data } = await testHydration( `