Skip to content

Commit 6264505

Browse files
authored
fix(runtime-core): inherit comment nodes during block patch in production build (#10748)
close #10747 close #12650
1 parent 8e34357 commit 6264505

File tree

2 files changed

+77
-7
lines changed

2 files changed

+77
-7
lines changed

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

+71-1
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,19 @@ import {
1414
h as originalH,
1515
ref,
1616
render,
17+
serialize,
1718
serializeInner,
1819
withDirectives,
1920
} from '@vue/runtime-test'
20-
import { Fragment, createCommentVNode, createVNode } from '../../src/vnode'
21+
import {
22+
Fragment,
23+
createBlock,
24+
createCommentVNode,
25+
createTextVNode,
26+
createVNode,
27+
openBlock,
28+
} from '../../src/vnode'
29+
import { toDisplayString } from '@vue/shared'
2130
import { compile, createApp as createDOMApp, render as domRender } from 'vue'
2231
import type { HMRRuntime } from '../../src/hmr'
2332

@@ -248,6 +257,39 @@ describe('renderer: teleport', () => {
248257
expect(serializeInner(target)).toBe(`teleported`)
249258
})
250259

260+
test('should traverse comment node after updating in optimize mode', async () => {
261+
const target = nodeOps.createElement('div')
262+
const root = nodeOps.createElement('div')
263+
const count = ref(0)
264+
let teleport
265+
266+
__DEV__ = false
267+
render(
268+
h(() => {
269+
teleport =
270+
(openBlock(),
271+
createBlock(Teleport, { to: target }, [
272+
createCommentVNode('comment in teleport'),
273+
]))
274+
return h('div', null, [
275+
createTextVNode(toDisplayString(count.value)),
276+
teleport,
277+
])
278+
}),
279+
root,
280+
)
281+
const commentNode = teleport!.children[0].el
282+
expect(serializeInner(root)).toBe(`<div>0</div>`)
283+
expect(serializeInner(target)).toBe(`<!--comment in teleport-->`)
284+
expect(serialize(commentNode)).toBe(`<!--comment in teleport-->`)
285+
286+
count.value = 1
287+
await nextTick()
288+
__DEV__ = true
289+
expect(serializeInner(root)).toBe(`<div>1</div>`)
290+
expect(teleport!.children[0].el).toBe(commentNode)
291+
})
292+
251293
test('should remove children when unmounted', () => {
252294
const target = nodeOps.createElement('div')
253295
const root = nodeOps.createElement('div')
@@ -274,6 +316,34 @@ describe('renderer: teleport', () => {
274316
testUnmount({ to: null, disabled: true })
275317
})
276318

319+
// #10747
320+
test('should unmount correctly when using top level comment in teleport', async () => {
321+
const target = nodeOps.createElement('div')
322+
const root = nodeOps.createElement('div')
323+
const count = ref(0)
324+
325+
__DEV__ = false
326+
render(
327+
h(() => {
328+
return h('div', null, [
329+
createTextVNode(toDisplayString(count.value)),
330+
(openBlock(),
331+
createBlock(Teleport, { to: target }, [
332+
createCommentVNode('comment in teleport'),
333+
])),
334+
])
335+
}),
336+
root,
337+
)
338+
339+
count.value = 1
340+
341+
await nextTick()
342+
__DEV__ = true
343+
render(null, root)
344+
expect(root.children.length).toBe(0)
345+
})
346+
277347
test('component with multi roots should be removed when unmounted', () => {
278348
const target = nodeOps.createElement('div')
279349
const root = nodeOps.createElement('div')

packages/runtime-core/src/renderer.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -2503,13 +2503,13 @@ export function traverseStaticChildren(
25032503
if (c2.type === Text) {
25042504
c2.el = c1.el
25052505
}
2506-
if (__DEV__) {
2507-
// #2324 also inherit for comment nodes, but not placeholders (e.g. v-if which
2508-
// would have received .el during block patch)
2509-
if (c2.type === Comment && !c2.el) {
2510-
c2.el = c1.el
2511-
}
2506+
// #2324 also inherit for comment nodes, but not placeholders (e.g. v-if which
2507+
// would have received .el during block patch)
2508+
if (c2.type === Comment && !c2.el) {
2509+
c2.el = c1.el
2510+
}
25122511

2512+
if (__DEV__) {
25132513
c2.el && (c2.el.__vnode = c2)
25142514
}
25152515
}

0 commit comments

Comments
 (0)