Skip to content

Commit 08bf7e3

Browse files
committed
fix(runtime-core): cloned vnodes with extra props should de-opt
1 parent ac6a6f1 commit 08bf7e3

File tree

4 files changed

+16
-10
lines changed

4 files changed

+16
-10
lines changed

packages/runtime-core/src/componentRenderUtils.ts

-5
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,6 @@ export function renderComponentRoot(
113113
root.shapeFlag & ShapeFlags.COMPONENT
114114
) {
115115
root = cloneVNode(root, fallthroughAttrs)
116-
// If the child root node is a compiler optimized vnode, make sure it
117-
// force update full props to account for the merged attrs.
118-
if (root.dynamicChildren) {
119-
root.patchFlag |= PatchFlags.FULL_PROPS
120-
}
121116
} else if (__DEV__ && !accessedAttrs && root.type !== Comment) {
122117
const allAttrs = Object.keys(attrs)
123118
const eventAttrs: string[] = []

packages/runtime-core/src/renderer.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,11 @@ function baseCreateRenderer(
354354
n1 = null
355355
}
356356

357+
if (n2.patchFlag === PatchFlags.BAIL) {
358+
optimized = false
359+
n2.dynamicChildren = null
360+
}
361+
357362
const { type, ref, shapeFlag } = n2
358363
switch (type) {
359364
case Text:
@@ -1280,9 +1285,6 @@ function baseCreateRenderer(
12801285
const c2 = n2.children
12811286

12821287
const { patchFlag, shapeFlag } = n2
1283-
if (patchFlag === PatchFlags.BAIL) {
1284-
optimized = false
1285-
}
12861288
// fast path
12871289
if (patchFlag > 0) {
12881290
if (patchFlag & PatchFlags.KEYED_FRAGMENT) {

packages/runtime-core/src/vnode.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,15 @@ export function cloneVNode<T, U>(
412412
target: vnode.target,
413413
targetAnchor: vnode.targetAnchor,
414414
shapeFlag: vnode.shapeFlag,
415-
patchFlag: vnode.patchFlag,
415+
// if the vnode is cloned with extra props, we can no longer assume its
416+
// existing patch flag to be reliable and need to bail out of optimized mode.
417+
// however we don't want block nodes to de-opt their children, so if the
418+
// vnode is a block node, we only add the FULL_PROPS flag to it.
419+
patchFlag: extraProps
420+
? vnode.dynamicChildren
421+
? vnode.patchFlag | PatchFlags.FULL_PROPS
422+
: PatchFlags.BAIL
423+
: vnode.patchFlag,
416424
dynamicProps: vnode.dynamicProps,
417425
dynamicChildren: vnode.dynamicChildren,
418426
appContext: vnode.appContext,

packages/shared/src/patchFlags.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ export const enum PatchFlags {
7676
HOISTED = -1,
7777

7878
// A special flag that indicates that the diffing algorithm should bail out
79-
// of optimized mode. This is only on block fragments created by renderSlot()
79+
// of optimized mode. For example, on block fragments created by renderSlot()
8080
// when encountering non-compiler generated slots (i.e. manually written
8181
// render functions, which should always be fully diffed)
82+
// OR manually cloneVNodes
8283
BAIL = -2
8384
}
8485

0 commit comments

Comments
 (0)