From 700f49ee964dba045ae6da89df6054313b52d533 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sun, 27 Apr 2025 12:01:42 +0800 Subject: [PATCH] wip: hydration for slots --- .../__tests__/ssrComponent.spec.ts | 4 +- .../compiler-ssr/__tests__/ssrVFor.spec.ts | 16 +- .../compiler-ssr/__tests__/ssrVIf.spec.ts | 2 +- .../compiler-ssr/__tests__/ssrVModel.spec.ts | 2 +- .../compiler-ssr/src/ssrCodegenTransform.ts | 1 + .../compiler-ssr/src/transforms/ssrVFor.ts | 5 +- packages/runtime-core/src/hydration.ts | 2 +- .../runtime-vapor/__tests__/hydration.spec.ts | 389 +++++++++++++++--- packages/runtime-vapor/src/apiCreateFor.ts | 26 +- packages/runtime-vapor/src/block.ts | 4 +- packages/runtime-vapor/src/component.ts | 8 +- packages/runtime-vapor/src/dom/hydration.ts | 19 +- packages/runtime-vapor/src/dom/node.ts | 53 ++- packages/runtime-vapor/src/insertionState.ts | 7 +- .../src/helpers/ssrRenderSlot.ts | 2 +- 15 files changed, 441 insertions(+), 99 deletions(-) diff --git a/packages/compiler-ssr/__tests__/ssrComponent.spec.ts b/packages/compiler-ssr/__tests__/ssrComponent.spec.ts index 1bae37c0f..fb2fff865 100644 --- a/packages/compiler-ssr/__tests__/ssrComponent.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrComponent.spec.ts @@ -246,7 +246,7 @@ describe('ssr: components', () => { _ssrRenderList(list, (i) => { _push(\`\`) }) - _push(\`\`) + _push(\`\`) _push(\`\`) } else { _push(\`\`) @@ -270,7 +270,7 @@ describe('ssr: components', () => { _ssrRenderList(_ctx.list, (i) => { _push(\`\`) }) - _push(\`\`) + _push(\`\`) _push(\`\`) } else { _push(\`\`) diff --git a/packages/compiler-ssr/__tests__/ssrVFor.spec.ts b/packages/compiler-ssr/__tests__/ssrVFor.spec.ts index 0d9572651..dad426de0 100644 --- a/packages/compiler-ssr/__tests__/ssrVFor.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrVFor.spec.ts @@ -10,7 +10,7 @@ describe('ssr: v-for', () => { _ssrRenderList(_ctx.list, (i) => { _push(\`
\`) }) - _push(\`\`) + _push(\`\`) }" `) }) @@ -25,7 +25,7 @@ describe('ssr: v-for', () => { _ssrRenderList(_ctx.list, (i) => { _push(\`
foobar
\`) }) - _push(\`\`) + _push(\`\`) }" `) }) @@ -51,9 +51,9 @@ describe('ssr: v-for', () => { _ssrInterpolate(j) }\`) }) - _push(\`\`) + _push(\`\`) }) - _push(\`\`) + _push(\`\`) }" `) }) @@ -68,7 +68,7 @@ describe('ssr: v-for', () => { _ssrRenderList(_ctx.list, (i) => { _push(\`\${_ssrInterpolate(i)}\`) }) - _push(\`\`) + _push(\`\`) }" `) }) @@ -85,7 +85,7 @@ describe('ssr: v-for', () => { _ssrRenderList(_ctx.list, (i) => { _push(\`\${_ssrInterpolate(i)}\`) }) - _push(\`\`) + _push(\`\`) }" `) }) @@ -107,7 +107,7 @@ describe('ssr: v-for', () => { _ssrInterpolate(i + 1) }\`) }) - _push(\`\`) + _push(\`\`) }" `) }) @@ -127,7 +127,7 @@ describe('ssr: v-for', () => { _ssrRenderList(_ctx.list, ({ foo }, index) => { _push(\`
\${_ssrInterpolate(foo + _ctx.bar + index)}
\`) }) - _push(\`\`) + _push(\`\`) }" `) }) diff --git a/packages/compiler-ssr/__tests__/ssrVIf.spec.ts b/packages/compiler-ssr/__tests__/ssrVIf.spec.ts index e8909a828..840d48508 100644 --- a/packages/compiler-ssr/__tests__/ssrVIf.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrVIf.spec.ts @@ -147,7 +147,7 @@ describe('ssr: v-if', () => { _ssrRenderList(_ctx.list, (i) => { _push(\`
\`) }) - _push(\`\`) + _push(\`\`) _push(\`\`) } else { _push(\`\`) diff --git a/packages/compiler-ssr/__tests__/ssrVModel.spec.ts b/packages/compiler-ssr/__tests__/ssrVModel.spec.ts index db4af81d0..c88f6ba31 100644 --- a/packages/compiler-ssr/__tests__/ssrVModel.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrVModel.spec.ts @@ -70,7 +70,7 @@ describe('ssr: v-model', () => { : _ssrLooseEqual(_ctx.model, i))) ? " selected" : "" }>\`) }) - _push(\`\`) + _push(\`\`) }" `) diff --git a/packages/compiler-ssr/src/ssrCodegenTransform.ts b/packages/compiler-ssr/src/ssrCodegenTransform.ts index 56f38b9e5..29f198370 100644 --- a/packages/compiler-ssr/src/ssrCodegenTransform.ts +++ b/packages/compiler-ssr/src/ssrCodegenTransform.ts @@ -381,6 +381,7 @@ function processChildrenDynamicInfo( * // Dynamic node -> should be wrapped * // Dynamic node -> should NOT be wrapped * // Static node + * */ function shouldProcessChildAsDynamic( parent: { tag?: string; children: TemplateChildNode[] }, diff --git a/packages/compiler-ssr/src/transforms/ssrVFor.ts b/packages/compiler-ssr/src/transforms/ssrVFor.ts index 827650785..251b1fef5 100644 --- a/packages/compiler-ssr/src/transforms/ssrVFor.ts +++ b/packages/compiler-ssr/src/transforms/ssrVFor.ts @@ -49,8 +49,7 @@ export function ssrProcessFor( ) if (!disableNestedFragments) { context.pushStringPart(``) - } else { - // add anchor for non-fragment v-for - context.pushStringPart(``) } + // v-for anchor for vapor hydration + context.pushStringPart(``) } diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index 4c8be2281..6c702f683 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -125,7 +125,7 @@ export function createHydrationFunctions( let n = next(node) // skip if: // - dynamic anchors (``, ``) - // - dynamic fragment end anchors (e.g. ``, ``) + // - vapor fragment end anchors (e.g. ``, ``) if (n && (isDynamicAnchor(n) || isVaporFragmentEndAnchor(n))) { n = next(n) } diff --git a/packages/runtime-vapor/__tests__/hydration.spec.ts b/packages/runtime-vapor/__tests__/hydration.spec.ts index 14faf569c..b0878e139 100644 --- a/packages/runtime-vapor/__tests__/hydration.spec.ts +++ b/packages/runtime-vapor/__tests__/hydration.spec.ts @@ -4,7 +4,12 @@ import { compileScript, parse } from '@vue/compiler-sfc' import * as runtimeVapor from '../src' import * as runtimeDom from '@vue/runtime-dom' import * as VueServerRenderer from '@vue/server-renderer' -import { DYNAMIC_COMPONENT_ANCHOR_LABEL, IF_ANCHOR_LABEL } from '@vue/shared' +import { + DYNAMIC_COMPONENT_ANCHOR_LABEL, + FOR_ANCHOR_LABEL, + IF_ANCHOR_LABEL, + SLOT_ANCHOR_LABEL, +} from '@vue/shared' const Vue = { ...runtimeDom, ...runtimeVapor } @@ -1438,6 +1443,9 @@ describe('Vapor Mode hydration', () => { }) describe('for', () => { + const forAnchorLabel = FOR_ANCHOR_LABEL + const slotAnchorLabel = SLOT_ANCHOR_LABEL + test('basic v-for', async () => { const { container, data } = await testHydration( `