From: daiwei Date: Tue, 5 Aug 2025 10:05:26 +0000 (+0800) Subject: wip: special handing anchors in ssr slot vnode fallback X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6454a295d7381a21422e35142c15a29d43494167;p=thirdparty%2Fvuejs%2Fcore.git wip: special handing anchors in ssr slot vnode fallback --- diff --git a/packages/runtime-vapor/src/apiCreateFor.ts b/packages/runtime-vapor/src/apiCreateFor.ts index 290136101c..249d03d717 100644 --- a/packages/runtime-vapor/src/apiCreateFor.ts +++ b/packages/runtime-vapor/src/apiCreateFor.ts @@ -13,9 +13,15 @@ import { } from '@vue/reactivity' import { FOR_ANCHOR_LABEL, isArray, isObject, isString } from '@vue/shared' import { createComment, createTextNode } from './dom/node' -import { type Block, insert, remove, remove as removeBlock } from './block' +import { + type Block, + insert, + normalizeAnchor, + remove, + remove as removeBlock, +} from './block' import { warn } from '@vue/runtime-dom' -import { currentInstance, isVaporComponent } from './component' +import { currentInstance } from './component' import type { DynamicSlot } from './componentSlots' import { renderEffect } from './renderEffect' import { VaporVForFlags } from '../../shared/src/vaporFlags' @@ -593,18 +599,6 @@ function getItem( } } -function normalizeAnchor(node: Block): Node | undefined { - if (node && node instanceof Node) { - return node - } else if (isArray(node)) { - return normalizeAnchor(node[0]) - } else if (isVaporComponent(node)) { - return normalizeAnchor(node.block!) - } else { - return normalizeAnchor(node.nodes!) - } -} - // runtime helper for rest element destructure export function getRestElement(val: any, keys: string[]): any { const res: any = {} diff --git a/packages/runtime-vapor/src/block.ts b/packages/runtime-vapor/src/block.ts index 617fdce516..04b0a4881c 100644 --- a/packages/runtime-vapor/src/block.ts +++ b/packages/runtime-vapor/src/block.ts @@ -157,6 +157,18 @@ export function remove(block: Block, parent?: ParentNode): void { } } +export function normalizeAnchor(node: Block): Node | undefined { + if (node && node instanceof Node) { + return node + } else if (isArray(node)) { + return normalizeAnchor(node[0]) + } else if (isVaporComponent(node)) { + return normalizeAnchor(node.block!) + } else { + return normalizeAnchor(node.nodes!) + } +} + /** * dev / test only */ diff --git a/packages/runtime-vapor/src/fragment.ts b/packages/runtime-vapor/src/fragment.ts index c4ddc92f9a..53d83adf3d 100644 --- a/packages/runtime-vapor/src/fragment.ts +++ b/packages/runtime-vapor/src/fragment.ts @@ -22,6 +22,7 @@ import { applyTransitionLeaveHooks, } from './components/Transition' import type { VaporComponentInstance } from './component' +import { normalizeAnchor } from './block' export class VaporFragment implements TransitionOptions @@ -161,18 +162,27 @@ export class DynamicFragment extends VaporFragment { this.anchor = locateVaporFragmentAnchor(currentHydrationNode!, '')! } else { this.anchor = locateVaporFragmentAnchor(currentHydrationNode!, label)! + // comment anchors are not included in ssr slot vnode fallback if (!this.anchor) { - // comment anchors are not included in ssr slot vnode fallback if (label === 'slot') { // fallback to fragment end anchor for this.anchor = locateVaporFragmentAnchor(currentHydrationNode!, ']')! } else { // create anchor - const { parentNode, nextSibling } = currentHydrationNode! - parentNode!.insertBefore( - (this.anchor = __DEV__ ? createComment(label) : createTextNode()), - nextSibling, - ) + if (isFragment(this.nodes) && this.nodes.anchor) { + // nested vapor fragment + const { parentNode, nextSibling } = this.nodes.anchor + parentNode!.insertBefore( + (this.anchor = __DEV__ ? createComment(label) : createTextNode()), + nextSibling, + ) + } else { + const { parentNode, nextSibling } = normalizeAnchor(this.nodes)! + parentNode!.insertBefore( + (this.anchor = __DEV__ ? createComment(label) : createTextNode()), + nextSibling, + ) + } } } }