]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(compiler/slot): bail out of optimization mode for non-compiled slots
authorEvan You <yyx990803@gmail.com>
Thu, 3 Oct 2019 19:09:09 +0000 (15:09 -0400)
committerEvan You <yyx990803@gmail.com>
Thu, 3 Oct 2019 19:09:09 +0000 (15:09 -0400)
packages/runtime-core/src/componentRenderUtils.ts
packages/runtime-core/src/createRenderer.ts
packages/runtime-core/src/helpers/renderSlot.ts
packages/shared/src/patchFlags.ts

index 0f9caab641f432065d6adc3b2c112ed41f1d62f4..f2973adbdc079f515c62464361afef97e0ec3346 100644 (file)
@@ -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
index 4fc55aed8abd42f72f56851df7e7de014e85bffe..8829b7389b80c8b4c5c645d2c9dc12ca451aac9d 100644 (file)
@@ -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
index c5a84aad9ebdcc7b1baa23ed4ec258f4eb3292b1..de633b22b14cb8ab62f0a529adbc498e9ee24208 100644 (file)
@@ -6,22 +6,24 @@ import {
   Fragment,
   VNode
 } from '../vnode'
+import { PatchFlags } from '@vue/shared'
 
 export function renderSlot(
   slots: Record<string, Slot>,
-  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
     )
   )
 }
index 74c8bf864105553f7b58c014f3e9ad5da45f2c8c..698aac0895895238730b87659a860e1ff50d1423 100644 (file)
@@ -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`
 }