@@ -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'
@@ -43,13 +46,11 @@ describe('component: slots', () => {
43
46
const t0 = template ( '<div></div>' )
44
47
const n0 = t0 ( )
45
48
instance = getCurrentInstance ( )
46
- const n1 = createSlot ( 'header' )
47
- insert ( n1 , n0 as any as ParentNode )
48
49
return n0
49
50
} ,
50
51
} )
51
52
52
- const { render, host } = define ( {
53
+ const { render } = define ( {
53
54
render ( ) {
54
55
return createComponent ( Comp , { } , { header : ( ) => template ( 'header' ) ( ) } )
55
56
} ,
@@ -60,8 +61,6 @@ describe('component: slots', () => {
60
61
expect ( instance . slots . header ( ) ) . toMatchObject (
61
62
document . createTextNode ( 'header' ) ,
62
63
)
63
-
64
- expect ( host . innerHTML ) . toBe ( '<div>header</div>' )
65
64
} )
66
65
67
66
// NOTE: slot normalization is not supported
@@ -243,4 +242,190 @@ describe('component: slots', () => {
243
242
'Slot "default" invoked outside of the render function' ,
244
243
) . not . toHaveBeenWarned ( )
245
244
} )
245
+
246
+ describe ( 'createSlot' , ( ) => {
247
+ test ( 'slot should be render correctly' , ( ) => {
248
+ const Comp = defineComponent ( ( ) => {
249
+ const n0 = template ( '<div></div>' ) ( )
250
+ insert ( createSlot ( 'header' ) , n0 as any as ParentNode )
251
+ return n0
252
+ } )
253
+
254
+ const { host } = define ( ( ) => {
255
+ return createComponent ( Comp , { } , { header : ( ) => template ( 'header' ) ( ) } )
256
+ } ) . render ( )
257
+
258
+ expect ( host . innerHTML ) . toBe ( '<div>header</div>' )
259
+ } )
260
+
261
+ test ( 'slot should be render correctly with binds' , async ( ) => {
262
+ const Comp = defineComponent ( ( ) => {
263
+ const n0 = template ( '<div></div>' ) ( )
264
+ insert (
265
+ createSlot ( 'header' , { title : ( ) => 'header' } ) ,
266
+ n0 as any as ParentNode ,
267
+ )
268
+ return n0
269
+ } )
270
+
271
+ const { host } = define ( ( ) => {
272
+ return createComponent (
273
+ Comp ,
274
+ { } ,
275
+ {
276
+ header : ( { title } ) => {
277
+ const el = template ( '<h1></h1>' ) ( )
278
+ renderEffect ( ( ) => {
279
+ setText ( el , title ( ) )
280
+ } )
281
+ return el
282
+ } ,
283
+ } ,
284
+ )
285
+ } ) . render ( )
286
+
287
+ expect ( host . innerHTML ) . toBe ( '<div><h1>header</h1></div>' )
288
+ } )
289
+
290
+ test ( 'dynamic slot should be render correctly with binds' , async ( ) => {
291
+ const Comp = defineComponent ( ( ) => {
292
+ const n0 = template ( '<div></div>' ) ( )
293
+ prepend (
294
+ n0 as any as ParentNode ,
295
+ createSlot ( 'header' , { title : ( ) => 'header' } ) ,
296
+ )
297
+ return n0
298
+ } )
299
+
300
+ const { host } = define ( ( ) => {
301
+ // dynamic slot
302
+ return createComponent ( Comp , { } , { } , ( ) => [
303
+ { name : 'header' , fn : ( { title } ) => template ( `${ title ( ) } ` ) ( ) } ,
304
+ ] )
305
+ } ) . render ( )
306
+
307
+ expect ( host . innerHTML ) . toBe ( '<div>header<!--slot--></div>' )
308
+ } )
309
+
310
+ test ( 'dynamic slot outlet should be render correctly with binds' , async ( ) => {
311
+ const Comp = defineComponent ( ( ) => {
312
+ const n0 = template ( '<div></div>' ) ( )
313
+ prepend (
314
+ n0 as any as ParentNode ,
315
+ createSlot (
316
+ ( ) => 'header' , // dynamic slot outlet name
317
+ { title : ( ) => 'header' } ,
318
+ ) ,
319
+ )
320
+ return n0
321
+ } )
322
+
323
+ const { host } = define ( ( ) => {
324
+ return createComponent (
325
+ Comp ,
326
+ { } ,
327
+ { header : ( { title } ) => template ( `${ title ( ) } ` ) ( ) } ,
328
+ )
329
+ } ) . render ( )
330
+
331
+ expect ( host . innerHTML ) . toBe ( '<div>header<!--slot--></div>' )
332
+ } )
333
+
334
+ test ( 'fallback should be render correctly' , ( ) => {
335
+ const Comp = defineComponent ( ( ) => {
336
+ const n0 = template ( '<div></div>' ) ( )
337
+ insert (
338
+ createSlot ( 'header' , { } , ( ) => template ( 'fallback' ) ( ) ) ,
339
+ n0 as any as ParentNode ,
340
+ )
341
+ return n0
342
+ } )
343
+
344
+ const { host } = define ( ( ) => {
345
+ return createComponent ( Comp , { } , { } )
346
+ } ) . render ( )
347
+
348
+ expect ( host . innerHTML ) . toBe ( '<div>fallback</div>' )
349
+ } )
350
+
351
+ test ( 'dynamic slot should be updated correctly' , async ( ) => {
352
+ const flag1 = ref ( true )
353
+
354
+ const Child = defineComponent ( ( ) => {
355
+ const temp0 = template ( '<p></p>' )
356
+ const el0 = temp0 ( )
357
+ const el1 = temp0 ( )
358
+ const slot1 = createSlot ( 'one' , { } , ( ) => template ( 'one fallback' ) ( ) )
359
+ const slot2 = createSlot ( 'two' , { } , ( ) => template ( 'two fallback' ) ( ) )
360
+ insert ( slot1 , el0 as any as ParentNode )
361
+ insert ( slot2 , el1 as any as ParentNode )
362
+ return [ el0 , el1 ]
363
+ } )
364
+
365
+ const { host } = define ( ( ) => {
366
+ return createComponent ( Child , { } , { } , ( ) => [
367
+ flag1 . value
368
+ ? { name : 'one' , fn : ( ) => template ( 'one content' ) ( ) }
369
+ : { name : 'two' , fn : ( ) => template ( 'two content' ) ( ) } ,
370
+ ] )
371
+ } ) . render ( )
372
+
373
+ expect ( host . innerHTML ) . toBe (
374
+ '<p>one content<!--slot--></p><p>two fallback<!--slot--></p>' ,
375
+ )
376
+
377
+ flag1 . value = false
378
+ await nextTick ( )
379
+
380
+ expect ( host . innerHTML ) . toBe (
381
+ '<p>one fallback<!--slot--></p><p>two content<!--slot--></p>' ,
382
+ )
383
+
384
+ flag1 . value = true
385
+ await nextTick ( )
386
+
387
+ expect ( host . innerHTML ) . toBe (
388
+ '<p>one content<!--slot--></p><p>two fallback<!--slot--></p>' ,
389
+ )
390
+ } )
391
+
392
+ test ( 'dynamic slot outlet should be updated correctly' , async ( ) => {
393
+ const slotOutletName = ref ( 'one' )
394
+
395
+ const Child = defineComponent ( ( ) => {
396
+ const temp0 = template ( '<p></p>' )
397
+ const el0 = temp0 ( )
398
+ const slot1 = createSlot (
399
+ ( ) => slotOutletName . value ,
400
+ { } ,
401
+ ( ) => template ( 'fallback' ) ( ) ,
402
+ )
403
+ insert ( slot1 , el0 as any as ParentNode )
404
+ return el0
405
+ } )
406
+
407
+ const { host } = define ( ( ) => {
408
+ return createComponent (
409
+ Child ,
410
+ { } ,
411
+ {
412
+ one : ( ) => template ( 'one content' ) ( ) ,
413
+ two : ( ) => template ( 'two content' ) ( ) ,
414
+ } ,
415
+ )
416
+ } ) . render ( )
417
+
418
+ expect ( host . innerHTML ) . toBe ( '<p>one content<!--slot--></p>' )
419
+
420
+ slotOutletName . value = 'two'
421
+ await nextTick ( )
422
+
423
+ expect ( host . innerHTML ) . toBe ( '<p>two content<!--slot--></p>' )
424
+
425
+ slotOutletName . value = 'none'
426
+ await nextTick ( )
427
+
428
+ expect ( host . innerHTML ) . toBe ( '<p>fallback<!--slot--></p>' )
429
+ } )
430
+ } )
246
431
} )
0 commit comments