]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
chore: update
authordaiwei <daiwei521@126.com>
Mon, 13 Oct 2025 09:47:07 +0000 (17:47 +0800)
committerdaiwei <daiwei521@126.com>
Mon, 13 Oct 2025 13:25:40 +0000 (21:25 +0800)
packages/runtime-core/src/hydration.ts
packages/runtime-vapor/src/dom/hydration.ts
packages/runtime-vapor/src/fragment.ts

index 34ae2180916fc53df003757f626ca14c065b30a1..e1c10afdbe36cc204355950ab41003e500870537 100644 (file)
@@ -312,7 +312,7 @@ export function createHydrationFunctions(
 
           // hydrate vapor component
           if ((vnode.type as ConcreteComponent).__vapor) {
-            nextNode = getVaporInterface(parentComponent, vnode).hydrate(
+            getVaporInterface(parentComponent, vnode).hydrate(
               vnode,
               node,
               container,
index a542b360cb69cd56fbfe3c59d99b4aa8c6060b9b..8d4cba1e023327992fa117f6cf1c08d5fb4984ef 100644 (file)
@@ -153,10 +153,12 @@ function adoptTemplateImpl(node: Node, template: string): Node | null {
   return node
 }
 
-function nextNode(node: Node): Node | null {
+export function locateNextNode(node: Node): Node | null {
   return isComment(node, '[')
-    ? locateEndAnchor(node as Anchor)!.nextSibling
-    : node.nextSibling
+    ? _next(locateEndAnchor(node)!)
+    : isComment(node, 'teleport start')
+      ? _next(locateEndAnchor(node, 'teleport start', 'teleport end')!)
+      : _next(node)
 }
 
 function locateHydrationNodeImpl(): void {
@@ -166,20 +168,20 @@ function locateHydrationNodeImpl(): void {
     // prepend
     if (insertionAnchor === 0) {
       node = insertionParent!.$lpn = lastPrepend
-        ? nextNode(lastPrepend)
+        ? locateNextNode(lastPrepend)
         : firstChild
     }
     // insert
     else if (insertionAnchor instanceof Node) {
       const { $lin: lastInsertedNode } = insertionAnchor as ChildItem
       node = (insertionAnchor as ChildItem).$lin = lastInsertedNode
-        ? nextNode(lastInsertedNode)
+        ? locateNextNode(lastInsertedNode)
         : insertionAnchor
     }
     // append
     else {
       node = insertionParent!.$lan = lastAppend
-        ? nextNode(lastAppend)
+        ? locateNextNode(lastAppend)
         : insertionAnchor === null
           ? firstChild
           : locateChildByLogicalIndex(insertionParent!, insertionAnchor)!
@@ -227,6 +229,14 @@ export function locateEndAnchor(
 
   return null
 }
+export function locateFragmentEndAnchor(label: string = ']'): Comment | null {
+  let node = currentHydrationNode!
+  while (node) {
+    if (isComment(node, label)) return node
+    node = node.nextSibling!
+  }
+  return null
+}
 
 function handleMismatch(node: Node, template: string): Node {
   if (!isMismatchAllowed(node.parentElement!, MismatchTypes.CHILDREN)) {
index 6f98e026b7c531aa9c789f2653624c3a2a429fd7..609e90b3f05ab7f15b9ca31e54fc17d83bd93a44 100644 (file)
@@ -14,6 +14,7 @@ import {
   currentHydrationNode,
   isComment,
   isHydrating,
+  locateFragmentEndAnchor,
   locateHydrationNode,
 } from './dom/hydration'
 import {
@@ -143,21 +144,21 @@ export class DynamicFragment extends VaporFragment {
     // avoid repeated hydration during fallback rendering
     if (this.anchor) return
 
-    // reuse the empty comment node as the anchor for empty if
-    // e.g. `<div v-if="false"></div>` -> `<!---->`
-    if (this.anchorLabel === 'if' && isEmpty) {
-      this.anchor = currentHydrationNode!
-      if (!this.anchor) {
-        throw new Error('Failed to locate if anchor')
-      } else {
-        if (__DEV__) {
-          ;(this.anchor as Comment).data = this.anchorLabel
+    if (this.anchorLabel === 'if') {
+      // reuse the empty comment node as the anchor for empty if
+      // e.g. `<div v-if="false"></div>` -> `<!---->`
+      if (isEmpty) {
+        this.anchor = locateFragmentEndAnchor('')!
+        if (!this.anchor) {
+          throw new Error('Failed to locate if anchor')
+        } else {
+          if (__DEV__) {
+            ;(this.anchor as Comment).data = this.anchorLabel
+          }
+          return
         }
-        return
       }
-    }
-
-    if (this.anchorLabel === 'slot') {
+    } else if (this.anchorLabel === 'slot') {
       // reuse the empty comment node for empty slot
       // e.g. `<slot v-if="false"></slot>`
       if (isEmpty && isComment(currentHydrationNode!, '')) {
@@ -168,8 +169,8 @@ export class DynamicFragment extends VaporFragment {
         return
       }
 
-      // reuse the vdom fragment end anchor for slots
-      this.anchor = currentHydrationNode!
+      // reuse the vdom fragment end anchor
+      this.anchor = locateFragmentEndAnchor()!
       if (!this.anchor) {
         throw new Error('Failed to locate slot anchor')
       } else {