]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
chore: remove unnecessary code
authordaiwei <daiwei521@126.com>
Thu, 14 Aug 2025 09:51:10 +0000 (17:51 +0800)
committerdaiwei <daiwei521@126.com>
Thu, 14 Aug 2025 09:51:51 +0000 (17:51 +0800)
forwarded slots anchors now in ssr output

packages/compiler-ssr/src/transforms/ssrVIf.ts
packages/runtime-vapor/__tests__/hydration.spec.ts
packages/runtime-vapor/src/apiCreateFor.ts
packages/runtime-vapor/src/fragment.ts
packages/runtime-vapor/src/vdomInterop.ts

index 17ac6311386a149f541088bb087fb0463181f4e0..f565c1be562a63b43154346d77b4e0751e8747a5 100644 (file)
@@ -81,7 +81,9 @@ export function ssrProcessIf(
 
   if (!currentIf.alternate && !disableComment) {
     currentIf.alternate = createBlockStatement([
-      createCallExpression(`_push`, ['`<!---->`']),
+      createCallExpression(`_push`, [
+        isVapor ? `\`<!--${IF_ANCHOR_LABEL}-->\`` : '`<!---->`',
+      ]),
     ])
   }
 }
index 3c9a5d336c3361a4dbbd231d7e89764014735d13..c356293e17fd55ac90a3fa2b91100443dd24dda4 100644 (file)
@@ -1229,14 +1229,14 @@ describe('Vapor Mode hydration', () => {
         undefined,
         data,
       )
-      // v-if="false" is rendered as <!----> in the server-rendered HTML
-      // it reused as anchor, so the anchor label is empty
-      expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(`"<!---->"`)
+      expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
+        `"<!--if-->"`,
+      )
 
       data.value = true
       await nextTick()
       expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
-        `"<div>foo</div><!---->"`,
+        `"<div>foo</div><!--if-->"`,
       )
     })
 
@@ -3082,6 +3082,51 @@ describe('VDOM interop', () => {
     )
   })
 
+  test('nested components (VDOM -> Vapor(with slot fallback) -> Vapor)', async () => {
+    const data = ref(true)
+    const { container } = await testHydrationInterop(
+      `<script setup>const data = _data; const components = _components;</script>
+          <template>
+            <components.VaporChild/>
+          </template>`,
+      {
+        VaporChild: {
+          code: `<template>
+            <components.VaporChild2>
+              <template #default>
+                <span>{{data}} vapor fallback</span>
+              </template>
+            </components.VaporChild2>
+          </template>`,
+          vapor: true,
+        },
+        VaporChild2: {
+          code: `<template><slot><span>vapor fallback2</span></slot></template>`,
+          vapor: true,
+        },
+      },
+      data,
+    )
+
+    expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
+      `
+      "
+      <!--[--><span>true vapor fallback</span><!--]-->
+      <!--slot-->"
+    `,
+    )
+
+    data.value = false
+    await nextTick()
+    expect(formatHtml(container.innerHTML)).toMatchInlineSnapshot(
+      `
+      "
+      <!--[--><span>false vapor fallback</span><!--]-->
+      <!--slot-->"
+    `,
+    )
+  })
+
   test('vapor slot render vdom component', async () => {
     const data = ref(true)
     const { container } = await testHydrationInterop(
index a34bc8b3ab27e2f9cd8520f8f402574648e73e06..e7a464648081d30e471d044bdd386b156eab39a4 100644 (file)
@@ -139,8 +139,10 @@ export const createFor = (
           currentHydrationNode!,
           FOR_ANCHOR_LABEL,
         )!
-        if (__DEV__ && !parentAnchor) {
-          // this should not happen
+        if (
+          (__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
+          !parentAnchor
+        ) {
           throw new Error(`v-for fragment anchor node was not found.`)
         }
       }
index 49c4a25fd7ad6aa6bdc958160504fc789dd42006..deb7b4c601f350b8b41de7baea29f8796ad9714d 100644 (file)
@@ -74,7 +74,7 @@ export class DynamicFragment extends VaporFragment {
 
   update(render?: BlockFn, key: any = render): void {
     if (key === this.current) {
-      if (isHydrating) this.hydrate(this.anchorLabel!, true)
+      if (isHydrating) this.hydrate(this.anchorLabel!)
       return
     }
     this.current = key
@@ -142,34 +142,14 @@ export class DynamicFragment extends VaporFragment {
     if (isHydrating) this.hydrate(this.anchorLabel!)
   }
 
-  hydrate = (label: string, isEmpty: boolean = false): void => {
+  hydrate = (label: string): void => {
     // avoid repeated hydration during rendering fallback
     if (this.anchor) return
 
-    // for `v-if="false"`, the node will be an empty comment, use it as the anchor.
-    // otherwise, find next sibling vapor fragment anchor
-    if (label === 'if' && isEmpty) {
-      this.anchor = locateVaporFragmentAnchor(currentHydrationNode!, '')!
-    } else {
-      this.anchor = locateVaporFragmentAnchor(currentHydrationNode!, label)!
-
-      // forwarded slots anchors are not present in ssr vnode-based slot
-      if (
-        !this.anchor &&
-        this.nodes instanceof DynamicFragment &&
-        this.nodes.forwarded
-      ) {
-        const { parentNode, nextSibling } = this.nodes.anchor
-        parentNode!.insertBefore(
-          (this.anchor = __DEV__ ? createComment(label) : createTextNode()),
-          nextSibling,
-        )
-      }
-    }
-
+    this.anchor = locateVaporFragmentAnchor(currentHydrationNode!, label)!
     if (this.anchor) {
       advanceHydrationNode(this.anchor)
-    } else if (__DEV__) {
+    } else if (__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) {
       throw new Error(`${label} fragment anchor node was not found.`)
     }
   }
index fe12fddbfd767998906cfb39b9dfbdd4b63fa154..63f1a1f611e186482e31b45538f4ee58842ac558 100644 (file)
@@ -43,7 +43,6 @@ import {
 import { type Block, type VaporTransitionHooks, insert, remove } from './block'
 import {
   EMPTY_OBJ,
-  SLOT_ANCHOR_LABEL,
   extend,
   isArray,
   isFunction,
@@ -183,9 +182,9 @@ const vaporInteropImpl: Omit<
   },
 
   hydrate(vnode, node, container, anchor, parentComponent) {
-    vaporHydrateNode(node, () => {
-      this.mount(vnode, container, anchor, parentComponent)
-    })
+    vaporHydrateNode(node, () =>
+      this.mount(vnode, container, anchor, parentComponent),
+    )
     return _next(node)
   },
 
@@ -196,8 +195,17 @@ const vaporInteropImpl: Omit<
       vnode.vb = slot(new Proxy(propsRef, vaporSlotPropsProxyHandler))
       vnode.el = vnode.anchor = locateVaporFragmentAnchor(
         currentHydrationNode!,
-        SLOT_ANCHOR_LABEL,
+        // there is not vapor slot anchor (<!--slot-->) injected in vdom component,
+        // so here use the fragment end anchor label
+        ']',
       )
+
+      if (
+        (__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
+        !vnode.anchor
+      ) {
+        throw new Error(`vapor slot anchor node was not found.`)
+      }
     })
     return _next(node)
   },