Forráskód Böngészése

fix(Teleport): fallback to non-optimized mode when HRM performing updates (#3311)

fix #3302
HcySunYang 5 éve
szülő
commit
9cb21d088e

+ 61 - 0
packages/runtime-core/__tests__/hmr.spec.ts

@@ -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>`
+    )
+  })
 })

+ 8 - 0
packages/runtime-core/src/components/Teleport.ts

@@ -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__