There is a component <Bar>
that inherits from a component <Foo>
.
The <Foo>
component defines a slot named content
with a fallback content. The <Bar>
component also defines a slot named content
with a different fallback content.
<!-- Foo.svelte -->
<slot name="content">
foo fallback
</slot>
<!-- Bar.svelte -->
<script>import Foo from './Foo.svelte'</script>
<Foo>
<span slot="content">
bar fallback
</span>
</Foo>
The <Bar>
component displays the fallback when called with <Foo/>
but it does not display the custom content when called with <Bar><span slot="content">bar custom</span></Bar>
.
Can you tell me what I am doing wrong?
<Foo/>
<!-- prints 'foo fallback': OK -->
<Foo>
<span slot="content">foo custom</span>
</Foo>
<!-- prints 'foo custom': OK -->
<Bar/>
<!-- prints 'bar fallback': OK -->
<Bar>
<span slot="content">bar custom</span>
</Bar>
<!-- prints 'bar fallback': KO - I would have expected 'bar custom' -->
Note that this code is oversimplified, and my real-world usecase is a bit more complex than this, and I need to use slots there.
The fiddle: https://svelte.dev/repl/5c525651eb8b4f60a6a696c1bd19f723
CodePudding user response:
It looks like you want to render slot content passed to Bar
in the slot defined by Foo
, but currently you haven't defined a slot in Bar
so there is nowhere for the passed content to be used, thus the fallback value is always passed to Foo
.
A solution might look something like the following, defining a content
slot in Bar
inside the span passed to Foo
's content slot.
// App.svelte
<script>
import Foo from './Foo.svelte'
import Bar from './Bar.svelte'
</script>
Expected: <em>bar custom</em><br>
<Bar>
<span slot="content">bar custom</span>
</Bar>
// ./Bar.svelte
<script>
import Foo from './Foo.svelte';
</script>
<Foo>
<span slot="content">
<slot name="content">bar fallback</slot>
</span>
</Foo>
// ./Foo.svelte
<slot name="content">
foo fallback
</slot>
CodePudding user response:
I think most of the answers were pretty close. I believe you can fix it by creating a slot with both content and name being the same value. Building off of your example (Repl with full 3rd level inheritance),
<!-- Foo.svelte -->
<slot name="content">
foo fallback
</slot>
<!-- Bar.svelte -->
<script>import Foo from './Foo.svelte'</script>
<Foo>
<slot name="content" slot="content">
bar fallback
</slot>
</Foo>
By doing it this way, we are both passing the slot through and including our new fallback.
If you were looking to make sure the span is there, that can be done by either putting it inside or outside of the slot
depending on your use case.
<!-- Bar.svelte -->
<script>import Foo from './Foo.svelte'</script>
<!-- option 1-->
<Foo>
<span>
<slot name="content" slot="content">
bar fallback
</slot>
</span>
</Foo>
<!-- option 2-->
<Foo>
<slot name="content" slot="content">
<span>
bar fallback
</span>
</slot>
</Foo>