From 5a7a1b8293822219283d6e267496bec02234b0bc Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 15 Feb 2021 15:09:27 -0500 Subject: [PATCH] fix(hmr): deep clone reused hoisted trees during dev fix vitejs/vite#2022 --- packages/runtime-core/src/vnode.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/src/vnode.ts b/packages/runtime-core/src/vnode.ts index ae69f7de834..92d7c4f428b 100644 --- a/packages/runtime-core/src/vnode.ts +++ b/packages/runtime-core/src/vnode.ts @@ -459,7 +459,7 @@ export function cloneVNode( ): VNode { // 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( : 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( } } +/** + * 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 */