Просмотр исходного кода

wip: special handing anchors in ssr slot vnode fallback

daiwei 10 месяцев назад
Родитель
Сommit
6454a295d7

+ 8 - 14
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 = {}

+ 12 - 0
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
  */

+ 16 - 6
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<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,
+            )
+          }
         }
       }
     }