]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(hmr): deep clone reused hoisted trees during dev
authorEvan You <yyx990803@gmail.com>
Mon, 15 Feb 2021 20:09:27 +0000 (15:09 -0500)
committerEvan You <yyx990803@gmail.com>
Mon, 15 Feb 2021 20:09:27 +0000 (15:09 -0500)
fix vitejs/vite#2022

packages/runtime-core/src/vnode.ts

index ae69f7de8340bd452979564c216a250e2be989aa..92d7c4f428b0f5bd0377793e2d8affe5d1a9d909 100644 (file)
@@ -459,7 +459,7 @@ export function cloneVNode<T, U>(
 ): VNode<T, U> {
   // This is intentionally NOT using spread or extend to avoid the runtime
   // key enumeration cost.
-  const { props, ref, patchFlag } = vnode
+  const { props, ref, patchFlag, children } = vnode
   const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props
   return {
     __v_isVNode: true,
@@ -479,7 +479,10 @@ export function cloneVNode<T, U>(
           : normalizeRef(extraProps)
         : ref,
     scopeId: vnode.scopeId,
-    children: vnode.children,
+    children:
+      __DEV__ && patchFlag === PatchFlags.HOISTED && isArray(children)
+        ? (children as VNode[]).map(deepCloneVNode)
+        : children,
     target: vnode.target,
     targetAnchor: vnode.targetAnchor,
     staticCount: vnode.staticCount,
@@ -513,6 +516,18 @@ export function cloneVNode<T, U>(
   }
 }
 
+/**
+ * Dev only, for HMR of hoisted vnodes reused in v-for
+ * https://github.com/vitejs/vite/issues/2022
+ */
+function deepCloneVNode(vnode: VNode): VNode {
+  const cloned = cloneVNode(vnode)
+  if (isArray(vnode.children)) {
+    cloned.children = (vnode.children as VNode[]).map(deepCloneVNode)
+  }
+  return cloned
+}
+
 /**
  * @private
  */