@@ -14,7 +14,7 @@ import {
1414 isFragment ,
1515} from './utils' ;
1616import { PatchFlags , PatchFlagNames } from './patchFlags' ;
17- import { State , ExcludesFalse } from './' ;
17+ import { State , ExcludesBoolean } from './' ;
1818
1919const xlinkRE = / ^ x l i n k ( [ A - Z ] ) / ;
2020const onRE = / ^ o n [ ^ a - z ] / ;
@@ -116,6 +116,7 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
116116 const directives : t . ArrayExpression [ ] = [ ] ;
117117 const dynamicPropNames = new Set ( ) ;
118118
119+ let slots : t . Identifier | t . Expression | null = null ;
119120 let patchFlag = 0 ;
120121
121122 if ( isFragment ( path . get ( 'openingElement' ) . get ( 'name' ) ) ) {
@@ -126,6 +127,7 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
126127 return {
127128 tag,
128129 isComponent,
130+ slots,
129131 props : t . nullLiteral ( ) ,
130132 directives,
131133 patchFlag,
@@ -201,7 +203,10 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
201203 value : attributeValue ,
202204 } ) ;
203205
204- if ( directive ) {
206+ if ( directiveName === 'slots' ) {
207+ slots = attributeValue ;
208+ return ;
209+ } else if ( directive ) {
205210 directives . push ( t . arrayExpression ( directive ) ) ;
206211 } else {
207212 // must be v-model and is a component
@@ -302,7 +307,7 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
302307 [
303308 ...exps ,
304309 ! ! objectProperties . length && t . objectExpression ( objectProperties ) ,
305- ] . filter ( Boolean as any as ExcludesFalse ) ,
310+ ] . filter ( Boolean as any as ExcludesBoolean ) ,
306311 ) ;
307312 } else {
308313 // single no need for a mergeProps call
@@ -316,6 +321,7 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
316321 tag,
317322 props : propsExpression ,
318323 isComponent,
324+ slots,
319325 directives,
320326 patchFlag,
321327 dynamicPropNames,
@@ -377,6 +383,7 @@ const transformJSXElement = (
377383 directives,
378384 patchFlag,
379385 dynamicPropNames,
386+ slots
380387 } = buildProps ( path , state ) ;
381388
382389 const { scope : { bindings } } = path ;
@@ -403,18 +410,25 @@ const transformJSXElement = (
403410 tag ,
404411 // @ts -ignore
405412 compatibleProps ? t . callExpression ( state . get ( 'compatibleProps' ) , [ props ] ) : props ,
406- ! ! children . length ? (
407- isComponent ? t . objectExpression ( [
408- t . objectProperty (
409- t . identifier ( 'default' ) ,
410- t . arrowFunctionExpression ( [ ] , t . arrayExpression ( children ) )
411- )
412- ] ) : t . arrayExpression ( children )
413+ ( children . length || slots ) ? (
414+ isComponent && ( children . length || slots )
415+ ? t . objectExpression ( [
416+ ! ! children . length && t . objectProperty (
417+ t . identifier ( 'default' ) ,
418+ t . arrowFunctionExpression ( [ ] , t . arrayExpression ( children ) )
419+ ) ,
420+ ...( slots ? (
421+ t . isObjectExpression ( slots )
422+ ? ( slots as any as t . ObjectExpression ) . properties
423+ : [ t . spreadElement ( slots as any ) ]
424+ ) : [ ] )
425+ ] . filter ( Boolean as any as ExcludesBoolean ) )
426+ : t . arrayExpression ( children )
413427 ) : t . nullLiteral ( ) ,
414428 ! ! patchFlag && t . addComment ( t . numericLiteral ( patchFlag ) , 'trailing' , ` ${ flagNames } ` , false ) ,
415429 ! ! dynamicPropNames . size
416430 && t . arrayExpression ( [ ...dynamicPropNames . keys ( ) ] . map ( ( name ) => t . stringLiteral ( name as string ) ) ) ,
417- ] . filter ( Boolean as any as ExcludesFalse ) ) ;
431+ ] . filter ( Boolean as any as ExcludesBoolean ) ) ;
418432
419433 if ( ! directives . length ) {
420434 return createVNode ;
0 commit comments