fix(hmr): deep clone reused hoisted trees during dev

fix vitejs/vite#2022
This commit is contained in:
Evan You 2021-02-15 15:09:27 -05:00
parent c69f4ea857
commit 5a7a1b8293

View File

@ -459,7 +459,7 @@ export function cloneVNode<T, U>(
): VNode<T, U> { ): VNode<T, U> {
// This is intentionally NOT using spread or extend to avoid the runtime // This is intentionally NOT using spread or extend to avoid the runtime
// key enumeration cost. // key enumeration cost.
const { props, ref, patchFlag } = vnode const { props, ref, patchFlag, children } = vnode
const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props
return { return {
__v_isVNode: true, __v_isVNode: true,
@ -479,7 +479,10 @@ export function cloneVNode<T, U>(
: normalizeRef(extraProps) : normalizeRef(extraProps)
: ref, : ref,
scopeId: vnode.scopeId, scopeId: vnode.scopeId,
children: vnode.children, children:
__DEV__ && patchFlag === PatchFlags.HOISTED && isArray(children)
? (children as VNode[]).map(deepCloneVNode)
: children,
target: vnode.target, target: vnode.target,
targetAnchor: vnode.targetAnchor, targetAnchor: vnode.targetAnchor,
staticCount: vnode.staticCount, 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 * @private
*/ */