fix(runtime-core): do not use bail patchFlag on cloned vnodes
fix #1665 - cloned vnodes with extra props will receive only the full props flag - this commit affects `cloneVNode` behavior when used in manual render functions. - ok for normal elements since elements only use patchFlags for own props optimization - full props flag is skipped for fragments because fragments use patchFlags only for children optimization - this also affects `shouldUpdateComponent` where it should now only respect patchFlags in optimized mode, since component vnodes use the patchFlag for both props and slots optimization checks.
This commit is contained in:
parent
324167d3d2
commit
6390ddfb7d
@ -279,7 +279,7 @@ export function shouldUpdateComponent(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patchFlag > 0) {
|
if (optimized && patchFlag > 0) {
|
||||||
if (patchFlag & PatchFlags.DYNAMIC_SLOTS) {
|
if (patchFlag & PatchFlags.DYNAMIC_SLOTS) {
|
||||||
// slot content that references values that might have changed,
|
// slot content that references values that might have changed,
|
||||||
// e.g. in a v-for
|
// e.g. in a v-for
|
||||||
@ -300,7 +300,7 @@ export function shouldUpdateComponent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!optimized) {
|
} else {
|
||||||
// this path is only taken by manually written render functions
|
// this path is only taken by manually written render functions
|
||||||
// so presence of any children leads to a forced update
|
// so presence of any children leads to a forced update
|
||||||
if (prevChildren || nextChildren) {
|
if (prevChildren || nextChildren) {
|
||||||
|
@ -310,7 +310,11 @@ function _createVNode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isVNode(type)) {
|
if (isVNode(type)) {
|
||||||
return cloneVNode(type, props, children)
|
const cloned = cloneVNode(type, props)
|
||||||
|
if (children) {
|
||||||
|
normalizeChildren(cloned, children)
|
||||||
|
}
|
||||||
|
return cloned
|
||||||
}
|
}
|
||||||
|
|
||||||
// class component normalization.
|
// class component normalization.
|
||||||
@ -420,8 +424,7 @@ function _createVNode(
|
|||||||
|
|
||||||
export function cloneVNode<T, U>(
|
export function cloneVNode<T, U>(
|
||||||
vnode: VNode<T, U>,
|
vnode: VNode<T, U>,
|
||||||
extraProps?: Data & VNodeProps | null,
|
extraProps?: Data & VNodeProps | null
|
||||||
children?: unknown
|
|
||||||
): VNode<T, U> {
|
): VNode<T, U> {
|
||||||
const props = extraProps
|
const props = extraProps
|
||||||
? vnode.props
|
? vnode.props
|
||||||
@ -430,7 +433,7 @@ export function cloneVNode<T, U>(
|
|||||||
: vnode.props
|
: vnode.props
|
||||||
// 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 cloned: VNode<T, U> = {
|
return {
|
||||||
__v_isVNode: true,
|
__v_isVNode: true,
|
||||||
__v_skip: true,
|
__v_skip: true,
|
||||||
type: vnode.type,
|
type: vnode.type,
|
||||||
@ -444,14 +447,11 @@ export function cloneVNode<T, U>(
|
|||||||
staticCount: vnode.staticCount,
|
staticCount: vnode.staticCount,
|
||||||
shapeFlag: vnode.shapeFlag,
|
shapeFlag: vnode.shapeFlag,
|
||||||
// if the vnode is cloned with extra props, we can no longer assume its
|
// if the vnode is cloned with extra props, we can no longer assume its
|
||||||
// existing patch flag to be reliable and need to bail out of optimized mode.
|
// existing patch flag to be reliable and need to add the FULL_PROPS flag.
|
||||||
// however we don't want block nodes to de-opt their children, so if the
|
patchFlag:
|
||||||
// vnode is a block node, we only add the FULL_PROPS flag to it.
|
extraProps && vnode.type !== Fragment
|
||||||
patchFlag: extraProps
|
|
||||||
? vnode.dynamicChildren
|
|
||||||
? vnode.patchFlag | PatchFlags.FULL_PROPS
|
? vnode.patchFlag | PatchFlags.FULL_PROPS
|
||||||
: PatchFlags.BAIL
|
: vnode.patchFlag,
|
||||||
: vnode.patchFlag,
|
|
||||||
dynamicProps: vnode.dynamicProps,
|
dynamicProps: vnode.dynamicProps,
|
||||||
dynamicChildren: vnode.dynamicChildren,
|
dynamicChildren: vnode.dynamicChildren,
|
||||||
appContext: vnode.appContext,
|
appContext: vnode.appContext,
|
||||||
@ -467,10 +467,6 @@ export function cloneVNode<T, U>(
|
|||||||
el: vnode.el,
|
el: vnode.el,
|
||||||
anchor: vnode.anchor
|
anchor: vnode.anchor
|
||||||
}
|
}
|
||||||
if (children) {
|
|
||||||
normalizeChildren(cloned, children)
|
|
||||||
}
|
|
||||||
return cloned
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user