]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): cloned vnodes with extra props should de-opt
authorEvan You <yyx990803@gmail.com>
Fri, 1 May 2020 18:55:27 +0000 (14:55 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 1 May 2020 18:55:27 +0000 (14:55 -0400)
packages/runtime-core/src/componentRenderUtils.ts
packages/runtime-core/src/renderer.ts
packages/runtime-core/src/vnode.ts
packages/shared/src/patchFlags.ts

index 4fd61895fa15117d0cd64ef44fa65bb07521d062..a83821b3b382ddf3e06e061adad39741c1cd820d 100644 (file)
@@ -113,11 +113,6 @@ export function renderComponentRoot(
         root.shapeFlag & ShapeFlags.COMPONENT
       ) {
         root = cloneVNode(root, fallthroughAttrs)
-        // If the child root node is a compiler optimized vnode, make sure it
-        // force update full props to account for the merged attrs.
-        if (root.dynamicChildren) {
-          root.patchFlag |= PatchFlags.FULL_PROPS
-        }
       } else if (__DEV__ && !accessedAttrs && root.type !== Comment) {
         const allAttrs = Object.keys(attrs)
         const eventAttrs: string[] = []
index 6cfdc85cc43ffb49bbee09edc5f7638e4e14b5dc..4152b7ded553b137d0e5378a88dfde5b5e17ba16 100644 (file)
@@ -354,6 +354,11 @@ function baseCreateRenderer(
       n1 = null
     }
 
+    if (n2.patchFlag === PatchFlags.BAIL) {
+      optimized = false
+      n2.dynamicChildren = null
+    }
+
     const { type, ref, shapeFlag } = n2
     switch (type) {
       case Text:
@@ -1280,9 +1285,6 @@ function baseCreateRenderer(
     const c2 = n2.children
 
     const { patchFlag, shapeFlag } = n2
-    if (patchFlag === PatchFlags.BAIL) {
-      optimized = false
-    }
     // fast path
     if (patchFlag > 0) {
       if (patchFlag & PatchFlags.KEYED_FRAGMENT) {
index d3e3ef4d8e1e06e8a87df724395212925a8a2d4d..efab10c6c8074e4ed0bdaeebde6e037ca6f691a0 100644 (file)
@@ -412,7 +412,15 @@ export function cloneVNode<T, U>(
     target: vnode.target,
     targetAnchor: vnode.targetAnchor,
     shapeFlag: vnode.shapeFlag,
-    patchFlag: vnode.patchFlag,
+    // if the vnode is cloned with extra props, we can no longer assume its
+    // existing patch flag to be reliable and need to bail out of optimized mode.
+    // however we don't want block nodes to de-opt their children, so if the
+    // vnode is a block node, we only add the FULL_PROPS flag to it.
+    patchFlag: extraProps
+      ? vnode.dynamicChildren
+        ? vnode.patchFlag | PatchFlags.FULL_PROPS
+        : PatchFlags.BAIL
+      : vnode.patchFlag,
     dynamicProps: vnode.dynamicProps,
     dynamicChildren: vnode.dynamicChildren,
     appContext: vnode.appContext,
index c541b2aba62c565c52d1f9843161a46234d5bf55..5ec63151739acbd947cc45f5c127c160afb0f8ae 100644 (file)
@@ -76,9 +76,10 @@ export const enum PatchFlags {
   HOISTED = -1,
 
   // A special flag that indicates that the diffing algorithm should bail out
-  // of optimized mode. This is only on block fragments created by renderSlot()
+  // of optimized mode. For example, on block fragments created by renderSlot()
   // when encountering non-compiler generated slots (i.e. manually written
   // render functions, which should always be fully diffed)
+  // OR manually cloneVNodes
   BAIL = -2
 }