]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(slots): compiled slot fallback should be functions (#1030)
authorunderfin <2218301630@qq.com>
Wed, 22 Apr 2020 20:52:41 +0000 (04:52 +0800)
committerGitHub <noreply@github.com>
Wed, 22 Apr 2020 20:52:41 +0000 (16:52 -0400)
This avoids it being collected as dynamic children when it's not used.

fix #1021

packages/compiler-core/__tests__/transforms/transformSlotOutlet.spec.ts
packages/compiler-core/src/transforms/transformSlotOutlet.ts
packages/runtime-core/src/helpers/renderSlot.ts

index 1bcd52d0ea9c6ea23599749eb9208f79afc1642c..d5e9f757582414849c4b43e0741c5663ec30b9c9 100644 (file)
@@ -216,12 +216,16 @@ describe('compiler: transform <slot> outlets', () => {
         `$slots`,
         `"default"`,
         `{}`,
-        [
-          {
-            type: NodeTypes.ELEMENT,
-            tag: `div`
-          }
-        ]
+        {
+          type: NodeTypes.JS_FUNCTION_EXPRESSION,
+          params: [],
+          returns: [
+            {
+              type: NodeTypes.ELEMENT,
+              tag: `div`
+            }
+          ]
+        }
       ]
     })
   })
@@ -235,12 +239,16 @@ describe('compiler: transform <slot> outlets', () => {
         `$slots`,
         `"foo"`,
         `{}`,
-        [
-          {
-            type: NodeTypes.ELEMENT,
-            tag: `div`
-          }
-        ]
+        {
+          type: NodeTypes.JS_FUNCTION_EXPRESSION,
+          params: [],
+          returns: [
+            {
+              type: NodeTypes.ELEMENT,
+              tag: `div`
+            }
+          ]
+        }
       ]
     })
   })
@@ -268,12 +276,16 @@ describe('compiler: transform <slot> outlets', () => {
             }
           ]
         },
-        [
-          {
-            type: NodeTypes.ELEMENT,
-            tag: `div`
-          }
-        ]
+        {
+          type: NodeTypes.JS_FUNCTION_EXPRESSION,
+          params: [],
+          returns: [
+            {
+              type: NodeTypes.ELEMENT,
+              tag: `div`
+            }
+          ]
+        }
       ]
     })
   })
@@ -301,12 +313,16 @@ describe('compiler: transform <slot> outlets', () => {
             }
           ]
         },
-        [
-          {
-            type: NodeTypes.ELEMENT,
-            tag: `div`
-          }
-        ]
+        {
+          type: NodeTypes.JS_FUNCTION_EXPRESSION,
+          params: [],
+          returns: [
+            {
+              type: NodeTypes.ELEMENT,
+              tag: `div`
+            }
+          ]
+        }
       ]
     })
   })
index da8ab81321007d9f778989be89c97245f224ab61..58ef0b2f488ef749d49ab71fb58f8b762c1b981e 100644 (file)
@@ -4,7 +4,8 @@ import {
   CallExpression,
   createCallExpression,
   ExpressionNode,
-  SlotOutletNode
+  SlotOutletNode,
+  createFunctionExpression
 } from '../ast'
 import { isSlotOutlet, findProp } from '../utils'
 import { buildProps, PropsExpression } from './transformElement'
@@ -29,7 +30,7 @@ export const transformSlotOutlet: NodeTransform = (node, context) => {
       if (!slotProps) {
         slotArgs.push(`{}`)
       }
-      slotArgs.push(children)
+      slotArgs.push(createFunctionExpression([], children, false, false, loc))
     }
 
     node.codegenNode = createCallExpression(
index 12f4b18d0614eafa6e5cff1d70cceabcdcb8052e..c0bfcaa7bf04e7f59f587e16cd986ce8b76d3370 100644 (file)
@@ -15,8 +15,8 @@ export function renderSlot(
   name: string,
   props: Data = {},
   // this is not a user-facing function, so the fallback is always generated by
-  // the compiler and guaranteed to be an array
-  fallback?: VNodeArrayChildren
+  // the compiler and guaranteed to be a function returning an array
+  fallback?: () => VNodeArrayChildren
 ): VNode {
   let slot = slots[name]
 
@@ -34,7 +34,7 @@ export function renderSlot(
     createBlock(
       Fragment,
       { key: props.key },
-      slot ? slot(props) : fallback || [],
+      slot ? slot(props) : fallback ? fallback() : [],
       slots._ ? PatchFlags.STABLE_FRAGMENT : PatchFlags.BAIL
     )
   )