]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: special handing anchors in ssr slot vnode fallback
authordaiwei <daiwei521@126.com>
Tue, 5 Aug 2025 10:05:26 +0000 (18:05 +0800)
committerdaiwei <daiwei521@126.com>
Tue, 5 Aug 2025 10:05:26 +0000 (18:05 +0800)
packages/runtime-vapor/src/apiCreateFor.ts
packages/runtime-vapor/src/block.ts
packages/runtime-vapor/src/fragment.ts

index 290136101c1e9435622d00e12c265e81502a0418..249d03d71738ff3a586e84450b1ec1a0debd8789 100644 (file)
@@ -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 = {}
index 617fdce51623300c53145d86604cb4a2d4e86cb2..04b0a4881cbff58337b95aed838bf5d80ad7c350 100644 (file)
@@ -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
  */
index c4ddc92f9af2e4e28d116612cb5a4cbef2cdc963..53d83adf3de695fc1e5d26ed55ffb21e5466aba8 100644 (file)
@@ -22,6 +22,7 @@ import {
   applyTransitionLeaveHooks,
 } from './components/Transition'
 import type { VaporComponentInstance } from './component'
+import { normalizeAnchor } from './block'
 
 export class VaporFragment<T extends Block = Block>
   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,
+            )
+          }
         }
       }
     }