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