root.shapeFlag & ShapeFlags.COMPONENT
) {
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) {
const allAttrs = Object.keys(attrs)
const eventAttrs: string[] = []
n1 = null
}
+ if (n2.patchFlag === PatchFlags.BAIL) {
+ optimized = false
+ n2.dynamicChildren = null
+ }
+
const { type, ref, shapeFlag } = n2
switch (type) {
case Text:
const c2 = n2.children
const { patchFlag, shapeFlag } = n2
- if (patchFlag === PatchFlags.BAIL) {
- optimized = false
- }
// fast path
if (patchFlag > 0) {
if (patchFlag & PatchFlags.KEYED_FRAGMENT) {
target: vnode.target,
targetAnchor: vnode.targetAnchor,
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,
dynamicChildren: vnode.dynamicChildren,
appContext: vnode.appContext,
HOISTED = -1,
// 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
// render functions, which should always be fully diffed)
+ // OR manually cloneVNodes
BAIL = -2
}