Skip to content

Commit 9cb21d0

Browse files
authored
fix(Teleport): fallback to non-optimized mode when HRM performing updates (#3311)
fix #3302
1 parent 8c3c14a commit 9cb21d0

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

packages/runtime-core/__tests__/hmr.spec.ts

+61
Original file line numberDiff line numberDiff line change
@@ -332,4 +332,65 @@ describe('hot module replacement', () => {
332332
rerender(last.__hmrId!, compileToFunction(`<Parent class="test"/>`))
333333
expect(serializeInner(root)).toBe(`<div class="test">child</div>`)
334334
})
335+
336+
// #3302
337+
test('rerender with Teleport', () => {
338+
const root = nodeOps.createElement('div')
339+
const target = nodeOps.createElement('div')
340+
const parentId = 'parent-teleport'
341+
342+
const Child: ComponentOptions = {
343+
data() {
344+
return {
345+
// style is used to ensure that the div tag will be tracked by Teleport
346+
style: {},
347+
target
348+
}
349+
},
350+
render: compileToFunction(`
351+
<teleport :to="target">
352+
<div :style="style">
353+
<slot/>
354+
</div>
355+
</teleport>
356+
`)
357+
}
358+
359+
const Parent: ComponentOptions = {
360+
__hmrId: parentId,
361+
components: { Child },
362+
render: compileToFunction(`
363+
<Child>
364+
<template #default>
365+
<div>1</div>
366+
</template>
367+
</Child>
368+
`)
369+
}
370+
createRecord(parentId, Parent)
371+
372+
render(h(Parent), root)
373+
expect(serializeInner(root)).toBe(
374+
`<!--teleport start--><!--teleport end-->`
375+
)
376+
expect(serializeInner(target)).toBe(`<div style={}><div>1</div></div>`)
377+
378+
rerender(
379+
parentId,
380+
compileToFunction(`
381+
<Child>
382+
<template #default>
383+
<div>1</div>
384+
<div>2</div>
385+
</template>
386+
</Child>
387+
`)
388+
)
389+
expect(serializeInner(root)).toBe(
390+
`<!--teleport start--><!--teleport end-->`
391+
)
392+
expect(serializeInner(target)).toBe(
393+
`<div style={}><div>1</div><div>2</div></div>`
394+
)
395+
})
335396
})

packages/runtime-core/src/components/Teleport.ts

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
import { VNode, VNodeArrayChildren, VNodeProps } from '../vnode'
1212
import { isString, ShapeFlags } from '@vue/shared'
1313
import { warn } from '../warning'
14+
import { isHmrUpdating } from '../hmr'
1415

1516
export type TeleportVNode = VNode<RendererNode, RendererElement, TeleportProps>
1617

@@ -85,6 +86,13 @@ export const TeleportImpl = {
8586
const disabled = isTeleportDisabled(n2.props)
8687
const { shapeFlag, children } = n2
8788

89+
// #3302
90+
// HMR updated, force full diff
91+
if (__DEV__ && isHmrUpdating) {
92+
optimized = false
93+
n2.dynamicChildren = null
94+
}
95+
8896
if (n1 == null) {
8997
// insert anchors in the main view
9098
const placeholder = (n2.el = __DEV__

0 commit comments

Comments
 (0)