From: Evan You Date: Thu, 3 Oct 2019 19:09:09 +0000 (-0400) Subject: feat(compiler/slot): bail out of optimization mode for non-compiled slots X-Git-Tag: v3.0.0-alpha.0~630 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=227ad034f057ee4a355e941536121e4d780ac761;p=thirdparty%2Fvuejs%2Fcore.git feat(compiler/slot): bail out of optimization mode for non-compiled slots --- diff --git a/packages/runtime-core/src/componentRenderUtils.ts b/packages/runtime-core/src/componentRenderUtils.ts index 0f9caab641..f2973adbdc 100644 --- a/packages/runtime-core/src/componentRenderUtils.ts +++ b/packages/runtime-core/src/componentRenderUtils.ts @@ -58,7 +58,7 @@ export function shouldUpdateComponent( ): boolean { const { props: prevProps, children: prevChildren } = prevVNode const { props: nextProps, children: nextChildren, patchFlag } = nextVNode - if (patchFlag) { + if (patchFlag > 0) { if (patchFlag & PatchFlags.DYNAMIC_SLOTS) { // slot content that references values that might have changed, // e.g. in a v-for diff --git a/packages/runtime-core/src/createRenderer.ts b/packages/runtime-core/src/createRenderer.ts index 4fc55aed8a..8829b7389b 100644 --- a/packages/runtime-core/src/createRenderer.ts +++ b/packages/runtime-core/src/createRenderer.ts @@ -409,7 +409,7 @@ export function createRenderer< invokeDirectiveHook(newProps.vnodeBeforeUpdate, parentComponent, n2, n1) } - if (patchFlag) { + if (patchFlag > 0) { // the presence of a patchFlag means this element's render code was // generated by the compiler and can take the fast path. // in this path old node and new node are guaranteed to have the same shape @@ -1227,9 +1227,12 @@ export function createRenderer< const prevShapeFlag = n1 ? n1.shapeFlag : 0 const c2 = n2.children - // fast path const { patchFlag, shapeFlag } = n2 - if (patchFlag) { + if (patchFlag === PatchFlags.BAIL) { + optimized = false + } + // fast path + if (patchFlag > 0) { if (patchFlag & PatchFlags.KEYED_FRAGMENT) { // this could be either fully-keyed or mixed (some keyed some not) // presence of patchFlag means children are guaranteed to be arrays diff --git a/packages/runtime-core/src/helpers/renderSlot.ts b/packages/runtime-core/src/helpers/renderSlot.ts index c5a84aad9e..de633b22b1 100644 --- a/packages/runtime-core/src/helpers/renderSlot.ts +++ b/packages/runtime-core/src/helpers/renderSlot.ts @@ -6,22 +6,24 @@ import { Fragment, VNode } from '../vnode' +import { PatchFlags } from '@vue/shared' export function renderSlot( slots: Record, - key: string, + name: string, props: any = {}, // this is not a user-facing function, so the fallback is always generated by // the compiler and gurunteed to be an array fallback?: VNodeChildren ): VNode { - const slot = slots[key] + const slot = slots[name] return ( openBlock(), createBlock( Fragment, { key: props.key }, - slot ? slot(props) : fallback || [] + slot ? slot(props) : fallback || [], + slots._compiled ? 0 : PatchFlags.BAIL ) ) } diff --git a/packages/shared/src/patchFlags.ts b/packages/shared/src/patchFlags.ts index 74c8bf8641..698aac0895 100644 --- a/packages/shared/src/patchFlags.ts +++ b/packages/shared/src/patchFlags.ts @@ -56,7 +56,13 @@ export const enum PatchFlags { // Indicates a component with dynamic slots (e.g. slot that references a v-for // iterated value, or dynamic slot names). // Components with this flag are always force updated. - DYNAMIC_SLOTS = 1 << 8 + DYNAMIC_SLOTS = 1 << 8, + + // A special flag that indicates that the diffing algorithm should bail out + // of optimized mode. This is only on block fragments created by renderSlot() + // when encountering non-compiler generated slots (i.e. manually written + // render functions, which should always be fully diffed) + BAIL = -1 } // runtime object for public consumption @@ -69,7 +75,8 @@ export const PublicPatchFlags = { FULL_PROPS: PatchFlags.FULL_PROPS, KEYED_FRAGMENT: PatchFlags.KEYED_FRAGMENT, UNKEYED_FRAGMENT: PatchFlags.UNKEYED_FRAGMENT, - DYNAMIC_SLOTS: PatchFlags.DYNAMIC_SLOTS + DYNAMIC_SLOTS: PatchFlags.DYNAMIC_SLOTS, + BAIL: PatchFlags.BAIL } // dev only flag -> name mapping @@ -82,5 +89,6 @@ export const PatchFlagNames = { [PatchFlags.FULL_PROPS]: `FULL_PROPS`, [PatchFlags.KEYED_FRAGMENT]: `KEYED_FRAGMENT`, [PatchFlags.UNKEYED_FRAGMENT]: `UNKEYED_FRAGMENT`, - [PatchFlags.DYNAMIC_SLOTS]: `DYNAMIC_SLOTS` + [PatchFlags.DYNAMIC_SLOTS]: `DYNAMIC_SLOTS`, + [PatchFlags.BAIL]: `BAIL` }