@@ -8,7 +8,10 @@ import {
8
8
getCurrentInstance ,
9
9
insert ,
10
10
nextTick ,
11
+ prepend ,
11
12
ref ,
13
+ renderEffect ,
14
+ setText ,
12
15
template ,
13
16
} from '../src'
14
17
import { makeRender } from './_utils'
@@ -58,13 +61,11 @@ describe('component: slots', () => {
58
61
const t0 = template ( '<div></div>' )
59
62
const n0 = t0 ( )
60
63
instance = getCurrentInstance ( )
61
- const n1 = createSlot ( 'header' )
62
- insert ( n1 , n0 as any as ParentNode )
63
64
return n0
64
65
} ,
65
66
} )
66
67
67
- const { render, host } = define ( {
68
+ const { render } = define ( {
68
69
render ( ) {
69
70
return createComponent ( Comp , { } , { header : ( ) => template ( 'header' ) ( ) } )
70
71
} ,
@@ -75,8 +76,6 @@ describe('component: slots', () => {
75
76
expect ( instance . slots . header ( ) ) . toMatchObject (
76
77
document . createTextNode ( 'header' ) ,
77
78
)
78
-
79
- expect ( host . innerHTML ) . toBe ( '<div>header</div>' )
80
79
} )
81
80
82
81
// runtime-core's "initSlots: instance.slots should be set correctly (when vnode.shapeFlag is not SLOTS_CHILDREN)"
@@ -194,4 +193,190 @@ describe('component: slots', () => {
194
193
'Slot "default" invoked outside of the render function' ,
195
194
) . not . toHaveBeenWarned ( )
196
195
} )
196
+
197
+ describe ( 'createSlot' , ( ) => {
198
+ test ( 'slot should be render correctly' , ( ) => {
199
+ const Comp = defineComponent ( ( ) => {
200
+ const n0 = template ( '<div></div>' ) ( )
201
+ insert ( createSlot ( 'header' ) , n0 as any as ParentNode )
202
+ return n0
203
+ } )
204
+
205
+ const { host } = define ( ( ) => {
206
+ return createComponent ( Comp , { } , { header : ( ) => template ( 'header' ) ( ) } )
207
+ } ) . render ( )
208
+
209
+ expect ( host . innerHTML ) . toBe ( '<div>header</div>' )
210
+ } )
211
+
212
+ test ( 'slot should be render correctly with binds' , async ( ) => {
213
+ const Comp = defineComponent ( ( ) => {
214
+ const n0 = template ( '<div></div>' ) ( )
215
+ insert (
216
+ createSlot ( 'header' , { title : ( ) => 'header' } ) ,
217
+ n0 as any as ParentNode ,
218
+ )
219
+ return n0
220
+ } )
221
+
222
+ const { host } = define ( ( ) => {
223
+ return createComponent (
224
+ Comp ,
225
+ { } ,
226
+ {
227
+ header : ( { title } ) => {
228
+ const el = template ( '<h1></h1>' ) ( )
229
+ renderEffect ( ( ) => {
230
+ setText ( el , title ( ) )
231
+ } )
232
+ return el
233
+ } ,
234
+ } ,
235
+ )
236
+ } ) . render ( )
237
+
238
+ expect ( host . innerHTML ) . toBe ( '<div><h1>header</h1></div>' )
239
+ } )
240
+
241
+ test ( 'dynamic slot should be render correctly with binds' , async ( ) => {
242
+ const Comp = defineComponent ( ( ) => {
243
+ const n0 = template ( '<div></div>' ) ( )
244
+ prepend (
245
+ n0 as any as ParentNode ,
246
+ createSlot ( 'header' , { title : ( ) => 'header' } ) ,
247
+ )
248
+ return n0
249
+ } )
250
+
251
+ const { host } = define ( ( ) => {
252
+ // dynamic slot
253
+ return createComponent ( Comp , { } , { } , ( ) => [
254
+ { name : 'header' , fn : ( { title } ) => template ( `${ title ( ) } ` ) ( ) } ,
255
+ ] )
256
+ } ) . render ( )
257
+
258
+ expect ( host . innerHTML ) . toBe ( '<div>header<!--slot--></div>' )
259
+ } )
260
+
261
+ test ( 'dynamic slot outlet should be render correctly with binds' , async ( ) => {
262
+ const Comp = defineComponent ( ( ) => {
263
+ const n0 = template ( '<div></div>' ) ( )
264
+ prepend (
265
+ n0 as any as ParentNode ,
266
+ createSlot (
267
+ ( ) => 'header' , // dynamic slot outlet name
268
+ { title : ( ) => 'header' } ,
269
+ ) ,
270
+ )
271
+ return n0
272
+ } )
273
+
274
+ const { host } = define ( ( ) => {
275
+ return createComponent (
276
+ Comp ,
277
+ { } ,
278
+ { header : ( { title } ) => template ( `${ title ( ) } ` ) ( ) } ,
279
+ )
280
+ } ) . render ( )
281
+
282
+ expect ( host . innerHTML ) . toBe ( '<div>header<!--slot--></div>' )
283
+ } )
284
+
285
+ test ( 'fallback should be render correctly' , ( ) => {
286
+ const Comp = defineComponent ( ( ) => {
287
+ const n0 = template ( '<div></div>' ) ( )
288
+ insert (
289
+ createSlot ( 'header' , { } , ( ) => template ( 'fallback' ) ( ) ) ,
290
+ n0 as any as ParentNode ,
291
+ )
292
+ return n0
293
+ } )
294
+
295
+ const { host } = define ( ( ) => {
296
+ return createComponent ( Comp , { } , { } )
297
+ } ) . render ( )
298
+
299
+ expect ( host . innerHTML ) . toBe ( '<div>fallback</div>' )
300
+ } )
301
+
302
+ test ( 'dynamic slot should be updated correctly' , async ( ) => {
303
+ const flag1 = ref ( true )
304
+
305
+ const Child = defineComponent ( ( ) => {
306
+ const temp0 = template ( '<p></p>' )
307
+ const el0 = temp0 ( )
308
+ const el1 = temp0 ( )
309
+ const slot1 = createSlot ( 'one' , { } , ( ) => template ( 'one fallback' ) ( ) )
310
+ const slot2 = createSlot ( 'two' , { } , ( ) => template ( 'two fallback' ) ( ) )
311
+ insert ( slot1 , el0 as any as ParentNode )
312
+ insert ( slot2 , el1 as any as ParentNode )
313
+ return [ el0 , el1 ]
314
+ } )
315
+
316
+ const { host } = define ( ( ) => {
317
+ return createComponent ( Child , { } , { } , ( ) => [
318
+ flag1 . value
319
+ ? { name : 'one' , fn : ( ) => template ( 'one content' ) ( ) }
320
+ : { name : 'two' , fn : ( ) => template ( 'two content' ) ( ) } ,
321
+ ] )
322
+ } ) . render ( )
323
+
324
+ expect ( host . innerHTML ) . toBe (
325
+ '<p>one content<!--slot--></p><p>two fallback<!--slot--></p>' ,
326
+ )
327
+
328
+ flag1 . value = false
329
+ await nextTick ( )
330
+
331
+ expect ( host . innerHTML ) . toBe (
332
+ '<p>one fallback<!--slot--></p><p>two content<!--slot--></p>' ,
333
+ )
334
+
335
+ flag1 . value = true
336
+ await nextTick ( )
337
+
338
+ expect ( host . innerHTML ) . toBe (
339
+ '<p>one content<!--slot--></p><p>two fallback<!--slot--></p>' ,
340
+ )
341
+ } )
342
+
343
+ test ( 'dynamic slot outlet should be updated correctly' , async ( ) => {
344
+ const slotOutletName = ref ( 'one' )
345
+
346
+ const Child = defineComponent ( ( ) => {
347
+ const temp0 = template ( '<p></p>' )
348
+ const el0 = temp0 ( )
349
+ const slot1 = createSlot (
350
+ ( ) => slotOutletName . value ,
351
+ { } ,
352
+ ( ) => template ( 'fallback' ) ( ) ,
353
+ )
354
+ insert ( slot1 , el0 as any as ParentNode )
355
+ return el0
356
+ } )
357
+
358
+ const { host } = define ( ( ) => {
359
+ return createComponent (
360
+ Child ,
361
+ { } ,
362
+ {
363
+ one : ( ) => template ( 'one content' ) ( ) ,
364
+ two : ( ) => template ( 'two content' ) ( ) ,
365
+ } ,
366
+ )
367
+ } ) . render ( )
368
+
369
+ expect ( host . innerHTML ) . toBe ( '<p>one content<!--slot--></p>' )
370
+
371
+ slotOutletName . value = 'two'
372
+ await nextTick ( )
373
+
374
+ expect ( host . innerHTML ) . toBe ( '<p>two content<!--slot--></p>' )
375
+
376
+ slotOutletName . value = 'none'
377
+ await nextTick ( )
378
+
379
+ expect ( host . innerHTML ) . toBe ( '<p>fallback<!--slot--></p>' )
380
+ } )
381
+ } )
197
382
} )
0 commit comments