Skip to content

Commit

Permalink
fix(runtime-core): fix dynamic node tracking in dynamic component tha…
Browse files Browse the repository at this point in the history
…t resolves to plain elements

fix #1039
  • Loading branch information
yyx990803 committed Apr 24, 2020
1 parent fa216a0 commit dcf2458
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
21 changes: 21 additions & 0 deletions packages/runtime-core/__tests__/vnode.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,27 @@ describe('vnode', () => {
]))
expect(vnode.dynamicChildren).toStrictEqual([vnode1])
})

// #1039
// <component :is="foo">{{ bar }}</component>
// - content is compiled as slot
// - dynamic component reoslves to plain element, but as a block
// - block creation disables its own tracking, accidentally causing the
// slot content (called during the block node creation) to be missed
test('element block should track normalized slot children', () => {
const hoist = createVNode('div')
let vnode1
const vnode = (openBlock(),
createBlock('div', null, {
default: () => {
return [
hoist,
(vnode1 = createVNode('div', null, 'text', PatchFlags.TEXT))
]
}
}))
expect(vnode.dynamicChildren).toStrictEqual([vnode1])
})
})

describe('transformVNodeArgs', () => {
Expand Down
16 changes: 11 additions & 5 deletions packages/runtime-core/src/vnode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,14 @@ export function createBlock(
patchFlag?: number,
dynamicProps?: string[]
): VNode {
// avoid a block with patchFlag tracking itself
shouldTrack--
const vnode = createVNode(type, props, children, patchFlag, dynamicProps)
shouldTrack++
const vnode = createVNode(
type,
props,
children,
patchFlag,
dynamicProps,
true /* isBlock: prevent a block from tracking itself */
)
// save current block children on the block vnode
vnode.dynamicChildren = currentBlock || EMPTY_ARR
// close block
Expand Down Expand Up @@ -244,7 +248,8 @@ function _createVNode(
props: (Data & VNodeProps) | null = null,
children: unknown = null,
patchFlag: number = 0,
dynamicProps: string[] | null = null
dynamicProps: string[] | null = null,
isBlockNode = false
): VNode {
if (!type) {
if (__DEV__) {
Expand Down Expand Up @@ -337,6 +342,7 @@ function _createVNode(
// the next vnode so that it can be properly unmounted later.
if (
shouldTrack > 0 &&
!isBlockNode &&
currentBlock &&
// the EVENTS flag is only for hydration and if it is the only flag, the
// vnode should not be considered dynamic due to handler caching.
Expand Down

0 comments on commit dcf2458

Please sign in to comment.