fix(runtime-core): cloned vnodes with extra props should de-opt
This commit is contained in:
parent
ac6a6f11ac
commit
08bf7e3607
@ -113,11 +113,6 @@ export function renderComponentRoot(
|
|||||||
root.shapeFlag & ShapeFlags.COMPONENT
|
root.shapeFlag & ShapeFlags.COMPONENT
|
||||||
) {
|
) {
|
||||||
root = cloneVNode(root, fallthroughAttrs)
|
root = cloneVNode(root, fallthroughAttrs)
|
||||||
// If the child root node is a compiler optimized vnode, make sure it
|
|
||||||
// force update full props to account for the merged attrs.
|
|
||||||
if (root.dynamicChildren) {
|
|
||||||
root.patchFlag |= PatchFlags.FULL_PROPS
|
|
||||||
}
|
|
||||||
} else if (__DEV__ && !accessedAttrs && root.type !== Comment) {
|
} else if (__DEV__ && !accessedAttrs && root.type !== Comment) {
|
||||||
const allAttrs = Object.keys(attrs)
|
const allAttrs = Object.keys(attrs)
|
||||||
const eventAttrs: string[] = []
|
const eventAttrs: string[] = []
|
||||||
|
@ -354,6 +354,11 @@ function baseCreateRenderer(
|
|||||||
n1 = null
|
n1 = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n2.patchFlag === PatchFlags.BAIL) {
|
||||||
|
optimized = false
|
||||||
|
n2.dynamicChildren = null
|
||||||
|
}
|
||||||
|
|
||||||
const { type, ref, shapeFlag } = n2
|
const { type, ref, shapeFlag } = n2
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Text:
|
case Text:
|
||||||
@ -1280,9 +1285,6 @@ function baseCreateRenderer(
|
|||||||
const c2 = n2.children
|
const c2 = n2.children
|
||||||
|
|
||||||
const { patchFlag, shapeFlag } = n2
|
const { patchFlag, shapeFlag } = n2
|
||||||
if (patchFlag === PatchFlags.BAIL) {
|
|
||||||
optimized = false
|
|
||||||
}
|
|
||||||
// fast path
|
// fast path
|
||||||
if (patchFlag > 0) {
|
if (patchFlag > 0) {
|
||||||
if (patchFlag & PatchFlags.KEYED_FRAGMENT) {
|
if (patchFlag & PatchFlags.KEYED_FRAGMENT) {
|
||||||
|
@ -412,7 +412,15 @@ export function cloneVNode<T, U>(
|
|||||||
target: vnode.target,
|
target: vnode.target,
|
||||||
targetAnchor: vnode.targetAnchor,
|
targetAnchor: vnode.targetAnchor,
|
||||||
shapeFlag: vnode.shapeFlag,
|
shapeFlag: vnode.shapeFlag,
|
||||||
patchFlag: vnode.patchFlag,
|
// 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.
|
||||||
|
// however we don't want block nodes to de-opt their children, so if the
|
||||||
|
// vnode is a block node, we only add the FULL_PROPS flag to it.
|
||||||
|
patchFlag: extraProps
|
||||||
|
? vnode.dynamicChildren
|
||||||
|
? vnode.patchFlag | PatchFlags.FULL_PROPS
|
||||||
|
: PatchFlags.BAIL
|
||||||
|
: vnode.patchFlag,
|
||||||
dynamicProps: vnode.dynamicProps,
|
dynamicProps: vnode.dynamicProps,
|
||||||
dynamicChildren: vnode.dynamicChildren,
|
dynamicChildren: vnode.dynamicChildren,
|
||||||
appContext: vnode.appContext,
|
appContext: vnode.appContext,
|
||||||
|
@ -76,9 +76,10 @@ export const enum PatchFlags {
|
|||||||
HOISTED = -1,
|
HOISTED = -1,
|
||||||
|
|
||||||
// A special flag that indicates that the diffing algorithm should bail out
|
// A special flag that indicates that the diffing algorithm should bail out
|
||||||
// of optimized mode. This is only on block fragments created by renderSlot()
|
// of optimized mode. For example, on block fragments created by renderSlot()
|
||||||
// when encountering non-compiler generated slots (i.e. manually written
|
// when encountering non-compiler generated slots (i.e. manually written
|
||||||
// render functions, which should always be fully diffed)
|
// render functions, which should always be fully diffed)
|
||||||
|
// OR manually cloneVNodes
|
||||||
BAIL = -2
|
BAIL = -2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user