]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): fix dynamic node tracking in dynamic component that resolves to...
authorEvan You <yyx990803@gmail.com>
Fri, 24 Apr 2020 16:18:51 +0000 (12:18 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 24 Apr 2020 16:18:51 +0000 (12:18 -0400)
fix #1039

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

index b89934566e8ff82f02adba3c5a0bb9597112cfec..7408eee8e5e8b69688e52963c699b196655fee10 100644 (file)
@@ -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', () => {
index 8f494472ddef46e3c6d76b2f128aac44fc729c2b..85b04166e042eaede42acf5508a40babc5907ea3 100644 (file)
@@ -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
@@ -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__) {
@@ -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.