diff --git a/packages/runtime-core/src/vnode.ts b/packages/runtime-core/src/vnode.ts index ae69f7de..92d7c4f4 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 */