1
1
import { ComponentInternalInstance , Slots } from 'vue'
2
- import { Props , PushFn , renderVNodeChildren } from '../render'
2
+ import { Props , PushFn , renderVNodeChildren , SSRBufferItem } from '../render'
3
3
4
4
export type SSRSlots = Record < string , SSRSlot >
5
5
export type SSRSlot = (
@@ -22,18 +22,46 @@ export function ssrRenderSlot(
22
22
const slotFn = slots [ slotName ]
23
23
if ( slotFn ) {
24
24
const scopeId = parentComponent && parentComponent . type . __scopeId
25
+ const slotBuffer : SSRBufferItem [ ] = [ ]
26
+ const bufferedPush = ( item : SSRBufferItem ) => {
27
+ slotBuffer . push ( item )
28
+ }
25
29
const ret = slotFn (
26
30
slotProps ,
27
- push ,
31
+ bufferedPush ,
28
32
parentComponent ,
29
33
scopeId ? ` ${ scopeId } -s` : ``
30
34
)
31
35
if ( Array . isArray ( ret ) ) {
32
36
// normal slot
33
37
renderVNodeChildren ( push , ret , parentComponent )
38
+ } else {
39
+ // ssr slot.
40
+ // check if the slot renders all comments, in which case use the fallback
41
+ let isEmptySlot = true
42
+ for ( let i = 0 ; i < slotBuffer . length ; i ++ ) {
43
+ if ( ! isComment ( slotBuffer [ i ] ) ) {
44
+ isEmptySlot = false
45
+ break
46
+ }
47
+ }
48
+ if ( isEmptySlot ) {
49
+ if ( fallbackRenderFn ) {
50
+ fallbackRenderFn ( )
51
+ }
52
+ } else {
53
+ for ( let i = 0 ; i < slotBuffer . length ; i ++ ) {
54
+ push ( slotBuffer [ i ] )
55
+ }
56
+ }
34
57
}
35
58
} else if ( fallbackRenderFn ) {
36
59
fallbackRenderFn ( )
37
60
}
38
61
push ( `<!--]-->` )
39
62
}
63
+
64
+ const commentRE = / ^ < ! - - .* - - > $ /
65
+ function isComment ( item : SSRBufferItem ) {
66
+ return typeof item === 'string' && commentRE . test ( item )
67
+ }
0 commit comments