From 032e2590b95fdc681c7ad227b0f9ee4ade6ed1b5 Mon Sep 17 00:00:00 2001 From: HcySunYang Date: Fri, 9 Apr 2021 12:01:32 +0800 Subject: [PATCH 1/3] fix(runtime-core): exit the optimization mode when the user manually renders the compiled slot --- .../runtime-core/src/componentRenderContext.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/src/componentRenderContext.ts b/packages/runtime-core/src/componentRenderContext.ts index 1771d9aa029..27aff595b33 100644 --- a/packages/runtime-core/src/componentRenderContext.ts +++ b/packages/runtime-core/src/componentRenderContext.ts @@ -1,6 +1,6 @@ import { ComponentInternalInstance } from './component' import { isRenderingCompiledSlot } from './helpers/renderSlot' -import { closeBlock, openBlock } from './vnode' +import { closeBlock, openBlock, VNode } from './vnode' /** * mark the current rendering instance for asset resolution (e.g. @@ -68,11 +68,21 @@ export function withCtx( openBlock(true /* null block that disables tracking */) } const prevInstance = setCurrentRenderingInstance(ctx) - const res = fn(...args) + const res: VNode[] = fn(...args) setCurrentRenderingInstance(prevInstance) if (!isRenderingCompiledSlot) { closeBlock() } + // #3569 + if (!isRenderingCompiledSlot) { + res.forEach(vnode => { + // when the user manually renders the compiled slot, + // it will be able to easily break the optimization update mode, + // so here we force to exit the optimization mode + vnode.dynamicChildren = null + vnode.patchFlag = 0 + }) + } return res } // mark this as a compiled slot function. From 44624b31ae74a26a9752481b74a2f5c2e96ee525 Mon Sep 17 00:00:00 2001 From: HcySunYang Date: Fri, 9 Apr 2021 12:08:42 +0800 Subject: [PATCH 2/3] fix: null value detection --- packages/runtime-core/src/componentRenderContext.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-core/src/componentRenderContext.ts b/packages/runtime-core/src/componentRenderContext.ts index 27aff595b33..fcff3f9e81e 100644 --- a/packages/runtime-core/src/componentRenderContext.ts +++ b/packages/runtime-core/src/componentRenderContext.ts @@ -74,7 +74,7 @@ export function withCtx( closeBlock() } // #3569 - if (!isRenderingCompiledSlot) { + if (!isRenderingCompiledSlot && res) { res.forEach(vnode => { // when the user manually renders the compiled slot, // it will be able to easily break the optimization update mode, From b740134da551d16b5c1cd14ef7903a7088e028ec Mon Sep 17 00:00:00 2001 From: HcySunYang Date: Fri, 9 Apr 2021 12:33:03 +0800 Subject: [PATCH 3/3] fix: recursively bailout --- .../src/componentRenderContext.ts | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/runtime-core/src/componentRenderContext.ts b/packages/runtime-core/src/componentRenderContext.ts index fcff3f9e81e..fdceab91f27 100644 --- a/packages/runtime-core/src/componentRenderContext.ts +++ b/packages/runtime-core/src/componentRenderContext.ts @@ -1,3 +1,4 @@ +import { ShapeFlags } from 'packages/shared/src/shapeFlags' import { ComponentInternalInstance } from './component' import { isRenderingCompiledSlot } from './helpers/renderSlot' import { closeBlock, openBlock, VNode } from './vnode' @@ -75,13 +76,7 @@ export function withCtx( } // #3569 if (!isRenderingCompiledSlot && res) { - res.forEach(vnode => { - // when the user manually renders the compiled slot, - // it will be able to easily break the optimization update mode, - // so here we force to exit the optimization mode - vnode.dynamicChildren = null - vnode.patchFlag = 0 - }) + forceBailout(res) } return res } @@ -91,3 +86,16 @@ export function withCtx( renderFnWithContext._c = true return renderFnWithContext } + +function forceBailout(vnodes: VNode[]) { + vnodes.forEach(vnode => { + // when the user manually renders the compiled slot, + // it will be able to easily break the optimization update mode, + // so here we force to exit the optimization mode + vnode.dynamicChildren = null + vnode.patchFlag = 0 + if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) { + forceBailout(vnode.children as VNode[]) + } + }) +}