Skip to content

Commit 6c99c7a

Browse files
committed
test: createSlot
1 parent 6364b10 commit 6c99c7a

File tree

2 files changed

+192
-7
lines changed

2 files changed

+192
-7
lines changed

packages/runtime-vapor/__tests__/componentSlots.spec.ts

Lines changed: 190 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ import {
88
getCurrentInstance,
99
insert,
1010
nextTick,
11+
prepend,
1112
ref,
13+
renderEffect,
14+
setText,
1215
template,
1316
} from '../src'
1417
import { makeRender } from './_utils'
@@ -43,13 +46,11 @@ describe('component: slots', () => {
4346
const t0 = template('<div></div>')
4447
const n0 = t0()
4548
instance = getCurrentInstance()
46-
const n1 = createSlot('header')
47-
insert(n1, n0 as any as ParentNode)
4849
return n0
4950
},
5051
})
5152

52-
const { render, host } = define({
53+
const { render } = define({
5354
render() {
5455
return createComponent(Comp, {}, { header: () => template('header')() })
5556
},
@@ -60,8 +61,6 @@ describe('component: slots', () => {
6061
expect(instance.slots.header()).toMatchObject(
6162
document.createTextNode('header'),
6263
)
63-
64-
expect(host.innerHTML).toBe('<div>header</div>')
6564
})
6665

6766
// NOTE: slot normalization is not supported
@@ -243,4 +242,190 @@ describe('component: slots', () => {
243242
'Slot "default" invoked outside of the render function',
244243
).not.toHaveBeenWarned()
245244
})
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+
})
246431
})

packages/runtime-vapor/src/componentSlots.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export function createSlot(
127127
}
128128
}
129129

130-
const getName = isDynamicName ? name : () => name
130+
const getSlot = isDynamicName ? () => slots[name()] : () => slots[name]
131131
const anchor = __DEV__ ? createComment('slot') : createTextNode()
132132
const fragment: Fragment = {
133133
nodes: [],
@@ -137,7 +137,7 @@ export function createSlot(
137137

138138
// TODO lifecycle hooks
139139
renderEffect(() => {
140-
if ((branch = slots[getName()] || fallback) !== oldBranch) {
140+
if ((branch = getSlot() || fallback) !== oldBranch) {
141141
parent ||= anchor.parentNode
142142
if (block) {
143143
scope!.stop()

0 commit comments

Comments
 (0)