Skip to content

Commit dcf2458

Browse files
committedApr 24, 2020
fix(runtime-core): fix dynamic node tracking in dynamic component that resolves to plain elements
fix #1039
1 parent fa216a0 commit dcf2458

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed
 

‎packages/runtime-core/__tests__/vnode.spec.ts

+21
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,27 @@ describe('vnode', () => {
337337
]))
338338
expect(vnode.dynamicChildren).toStrictEqual([vnode1])
339339
})
340+
341+
// #1039
342+
// <component :is="foo">{{ bar }}</component>
343+
// - content is compiled as slot
344+
// - dynamic component reoslves to plain element, but as a block
345+
// - block creation disables its own tracking, accidentally causing the
346+
// slot content (called during the block node creation) to be missed
347+
test('element block should track normalized slot children', () => {
348+
const hoist = createVNode('div')
349+
let vnode1
350+
const vnode = (openBlock(),
351+
createBlock('div', null, {
352+
default: () => {
353+
return [
354+
hoist,
355+
(vnode1 = createVNode('div', null, 'text', PatchFlags.TEXT))
356+
]
357+
}
358+
}))
359+
expect(vnode.dynamicChildren).toStrictEqual([vnode1])
360+
})
340361
})
341362

342363
describe('transformVNodeArgs', () => {

‎packages/runtime-core/src/vnode.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,14 @@ export function createBlock(
177177
patchFlag?: number,
178178
dynamicProps?: string[]
179179
): VNode {
180-
// avoid a block with patchFlag tracking itself
181-
shouldTrack--
182-
const vnode = createVNode(type, props, children, patchFlag, dynamicProps)
183-
shouldTrack++
180+
const vnode = createVNode(
181+
type,
182+
props,
183+
children,
184+
patchFlag,
185+
dynamicProps,
186+
true /* isBlock: prevent a block from tracking itself */
187+
)
184188
// save current block children on the block vnode
185189
vnode.dynamicChildren = currentBlock || EMPTY_ARR
186190
// close block
@@ -244,7 +248,8 @@ function _createVNode(
244248
props: (Data & VNodeProps) | null = null,
245249
children: unknown = null,
246250
patchFlag: number = 0,
247-
dynamicProps: string[] | null = null
251+
dynamicProps: string[] | null = null,
252+
isBlockNode = false
248253
): VNode {
249254
if (!type) {
250255
if (__DEV__) {
@@ -337,6 +342,7 @@ function _createVNode(
337342
// the next vnode so that it can be properly unmounted later.
338343
if (
339344
shouldTrack > 0 &&
345+
!isBlockNode &&
340346
currentBlock &&
341347
// the EVENTS flag is only for hydration and if it is the only flag, the
342348
// vnode should not be considered dynamic due to handler caching.

0 commit comments

Comments
 (0)