]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(Teleport): fallback to non-optimized mode when HRM performing updates (#3311)
authorHcySunYang <HcySunYang@outlook.com>
Fri, 26 Mar 2021 18:02:44 +0000 (02:02 +0800)
committerGitHub <noreply@github.com>
Fri, 26 Mar 2021 18:02:44 +0000 (14:02 -0400)
fix #3302

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

index ab2de223cdc80d3979cd86c404b7f807d44953eb..70af64853c5e659f2d4357b93e644315782e13fd 100644 (file)
@@ -332,4 +332,65 @@ describe('hot module replacement', () => {
     rerender(last.__hmrId!, compileToFunction(`<Parent class="test"/>`))
     expect(serializeInner(root)).toBe(`<div class="test">child</div>`)
   })
+
+  // #3302
+  test('rerender with Teleport', () => {
+    const root = nodeOps.createElement('div')
+    const target = nodeOps.createElement('div')
+    const parentId = 'parent-teleport'
+
+    const Child: ComponentOptions = {
+      data() {
+        return {
+          // style is used to ensure that the div tag will be tracked by Teleport
+          style: {},
+          target
+        }
+      },
+      render: compileToFunction(`
+        <teleport :to="target">
+          <div :style="style">
+            <slot/>
+          </div>
+        </teleport>
+      `)
+    }
+
+    const Parent: ComponentOptions = {
+      __hmrId: parentId,
+      components: { Child },
+      render: compileToFunction(`
+        <Child>
+          <template #default>
+            <div>1</div>
+          </template>
+        </Child>
+      `)
+    }
+    createRecord(parentId, Parent)
+
+    render(h(Parent), root)
+    expect(serializeInner(root)).toBe(
+      `<!--teleport start--><!--teleport end-->`
+    )
+    expect(serializeInner(target)).toBe(`<div style={}><div>1</div></div>`)
+
+    rerender(
+      parentId,
+      compileToFunction(`
+      <Child>
+        <template #default>
+          <div>1</div>
+          <div>2</div>
+        </template>
+      </Child>
+    `)
+    )
+    expect(serializeInner(root)).toBe(
+      `<!--teleport start--><!--teleport end-->`
+    )
+    expect(serializeInner(target)).toBe(
+      `<div style={}><div>1</div><div>2</div></div>`
+    )
+  })
 })
index 1b51a03ac94e306c4ad12b415a5b49b3a1761322..5bbe899e4c8ac53a3fdc9cdcb26df1767f99b192 100644 (file)
@@ -11,6 +11,7 @@ import {
 import { VNode, VNodeArrayChildren, VNodeProps } from '../vnode'
 import { isString, ShapeFlags } from '@vue/shared'
 import { warn } from '../warning'
+import { isHmrUpdating } from '../hmr'
 
 export type TeleportVNode = VNode<RendererNode, RendererElement, TeleportProps>
 
@@ -85,6 +86,13 @@ export const TeleportImpl = {
     const disabled = isTeleportDisabled(n2.props)
     const { shapeFlag, children } = n2
 
+    // #3302
+    // HMR updated, force full diff
+    if (__DEV__ && isHmrUpdating) {
+      optimized = false
+      n2.dynamicChildren = null
+    }
+
     if (n1 == null) {
       // insert anchors in the main view
       const placeholder = (n2.el = __DEV__