]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): fix attr fallthrough on compiled framgent w/ single static element...
authorEvan You <yyx990803@gmail.com>
Tue, 21 Jul 2020 17:09:58 +0000 (13:09 -0400)
committerEvan You <yyx990803@gmail.com>
Tue, 21 Jul 2020 17:11:19 +0000 (13:11 -0400)
packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts
packages/runtime-core/src/componentRenderUtils.ts
packages/runtime-core/src/vnode.ts

index d8452db58f92fd46dae7ad8775ccc8d0c243a1b0..ab18c842601814cf5ea823564238095aece3ed2e 100644 (file)
@@ -10,7 +10,8 @@ import {
   openBlock,
   createBlock,
   FunctionalComponent,
-  createCommentVNode
+  createCommentVNode,
+  Fragment
 } from '@vue/runtime-dom'
 import { mockWarn } from '@vue/shared'
 
@@ -573,12 +574,15 @@ describe('attribute fallthrough', () => {
     }
 
     const Child = {
-      setup(props: any) {
-        return () => [
-          createCommentVNode('hello'),
-          h('button'),
-          createCommentVNode('world')
-        ]
+      setup() {
+        return () => (
+          openBlock(),
+          createBlock(Fragment, null, [
+            createCommentVNode('hello'),
+            h('button'),
+            createCommentVNode('world')
+          ])
+        )
       }
     }
 
index bd1ce451df07ac68ad6cb6669ba83eb856897424..dad54bcadcae8367ad038be6a6d90f885057c7df 100644 (file)
@@ -215,6 +215,9 @@ export function renderComponentRoot(
   return result
 }
 
+/**
+ * dev only
+ */
 const getChildRoot = (
   vnode: VNode
 ): [VNode, ((root: VNode) => void) | undefined] => {
@@ -231,12 +234,14 @@ const getChildRoot = (
   }
   const childRoot = children[0]
   const index = rawChildren.indexOf(childRoot)
-  const dynamicIndex = dynamicChildren
-    ? dynamicChildren.indexOf(childRoot)
-    : null
+  const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1
   const setRoot = (updatedRoot: VNode) => {
     rawChildren[index] = updatedRoot
-    if (dynamicIndex !== null) dynamicChildren[dynamicIndex] = updatedRoot
+    if (dynamicIndex > -1) {
+      dynamicChildren[dynamicIndex] = updatedRoot
+    } else if (dynamicChildren && updatedRoot.patchFlag > 0) {
+      dynamicChildren.push(updatedRoot)
+    }
   }
   return [normalizeVNode(childRoot), setRoot]
 }
index 5cd08bc15c9203af9c58de627912347c396bce18..ba0a4cafb52d60f1988435c57c1c34ab518531fa 100644 (file)
@@ -426,19 +426,20 @@ export function cloneVNode<T, U>(
   vnode: VNode<T, U>,
   extraProps?: Data & VNodeProps | null
 ): VNode<T, U> {
-  const props = extraProps
-    ? vnode.props
-      ? mergeProps(vnode.props, extraProps)
-      : extend({}, extraProps)
-    : vnode.props
   // This is intentionally NOT using spread or extend to avoid the runtime
   // key enumeration cost.
+  const { props, patchFlag } = vnode
+  const mergedProps = extraProps
+    ? props
+      ? mergeProps(props, extraProps)
+      : extend({}, extraProps)
+    : props
   return {
     __v_isVNode: true,
     __v_skip: true,
     type: vnode.type,
-    props,
-    key: props && normalizeKey(props),
+    props: mergedProps,
+    key: mergedProps && normalizeKey(mergedProps),
     ref: extraProps && extraProps.ref ? normalizeRef(extraProps) : vnode.ref,
     scopeId: vnode.scopeId,
     children: vnode.children,
@@ -448,10 +449,14 @@ export function cloneVNode<T, U>(
     shapeFlag: vnode.shapeFlag,
     // if the vnode is cloned with extra props, we can no longer assume its
     // existing patch flag to be reliable and need to add the FULL_PROPS flag.
+    // note: perserve flag for fragments since they use the flag for children
+    // fast paths only.
     patchFlag:
       extraProps && vnode.type !== Fragment
-        ? vnode.patchFlag | PatchFlags.FULL_PROPS
-        : vnode.patchFlag,
+        ? patchFlag === -1 // hoisted node
+          ? PatchFlags.FULL_PROPS
+          : patchFlag | PatchFlags.FULL_PROPS
+        : patchFlag,
     dynamicProps: vnode.dynamicProps,
     dynamicChildren: vnode.dynamicChildren,
     appContext: vnode.appContext,