]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): inherit comment nodes during block patch in production build ...
authortonicli <263282263@qq.com>
Tue, 13 May 2025 14:18:28 +0000 (22:18 +0800)
committerGitHub <noreply@github.com>
Tue, 13 May 2025 14:18:28 +0000 (22:18 +0800)
close #10747
close #12650

packages/runtime-core/__tests__/components/Teleport.spec.ts
packages/runtime-core/src/renderer.ts

index 1229c5325b7fe95957376efc8f3ee37077d95004..4c35b1f2d79754c59c5edc48addf2023193ca311 100644 (file)
@@ -14,10 +14,19 @@ import {
   h as originalH,
   ref,
   render,
+  serialize,
   serializeInner,
   withDirectives,
 } from '@vue/runtime-test'
-import { Fragment, createCommentVNode, createVNode } from '../../src/vnode'
+import {
+  Fragment,
+  createBlock,
+  createCommentVNode,
+  createTextVNode,
+  createVNode,
+  openBlock,
+} from '../../src/vnode'
+import { toDisplayString } from '@vue/shared'
 import { compile, createApp as createDOMApp, render as domRender } from 'vue'
 import type { HMRRuntime } from '../../src/hmr'
 
@@ -248,6 +257,39 @@ describe('renderer: teleport', () => {
       expect(serializeInner(target)).toBe(`teleported`)
     })
 
+    test('should traverse comment node after updating in optimize mode', async () => {
+      const target = nodeOps.createElement('div')
+      const root = nodeOps.createElement('div')
+      const count = ref(0)
+      let teleport
+
+      __DEV__ = false
+      render(
+        h(() => {
+          teleport =
+            (openBlock(),
+            createBlock(Teleport, { to: target }, [
+              createCommentVNode('comment in teleport'),
+            ]))
+          return h('div', null, [
+            createTextVNode(toDisplayString(count.value)),
+            teleport,
+          ])
+        }),
+        root,
+      )
+      const commentNode = teleport!.children[0].el
+      expect(serializeInner(root)).toBe(`<div>0</div>`)
+      expect(serializeInner(target)).toBe(`<!--comment in teleport-->`)
+      expect(serialize(commentNode)).toBe(`<!--comment in teleport-->`)
+
+      count.value = 1
+      await nextTick()
+      __DEV__ = true
+      expect(serializeInner(root)).toBe(`<div>1</div>`)
+      expect(teleport!.children[0].el).toBe(commentNode)
+    })
+
     test('should remove children when unmounted', () => {
       const target = nodeOps.createElement('div')
       const root = nodeOps.createElement('div')
@@ -274,6 +316,34 @@ describe('renderer: teleport', () => {
       testUnmount({ to: null, disabled: true })
     })
 
+    // #10747
+    test('should unmount correctly when using top level comment in teleport', async () => {
+      const target = nodeOps.createElement('div')
+      const root = nodeOps.createElement('div')
+      const count = ref(0)
+
+      __DEV__ = false
+      render(
+        h(() => {
+          return h('div', null, [
+            createTextVNode(toDisplayString(count.value)),
+            (openBlock(),
+            createBlock(Teleport, { to: target }, [
+              createCommentVNode('comment in teleport'),
+            ])),
+          ])
+        }),
+        root,
+      )
+
+      count.value = 1
+
+      await nextTick()
+      __DEV__ = true
+      render(null, root)
+      expect(root.children.length).toBe(0)
+    })
+
     test('component with multi roots should be removed when unmounted', () => {
       const target = nodeOps.createElement('div')
       const root = nodeOps.createElement('div')
index e43348f85ea55883c6cb72b6744950ac5893e850..334858b7b3b3395c809a0ac9159233b4d47e847d 100644 (file)
@@ -2503,13 +2503,13 @@ export function traverseStaticChildren(
       if (c2.type === Text) {
         c2.el = c1.el
       }
-      if (__DEV__) {
-        // #2324 also inherit for comment nodes, but not placeholders (e.g. v-if which
-        // would have received .el during block patch)
-        if (c2.type === Comment && !c2.el) {
-          c2.el = c1.el
-        }
+      // #2324 also inherit for comment nodes, but not placeholders (e.g. v-if which
+      // would have received .el during block patch)
+      if (c2.type === Comment && !c2.el) {
+        c2.el = c1.el
+      }
 
+      if (__DEV__) {
         c2.el && (c2.el.__vnode = c2)
       }
     }