简体   繁体   中英

How to inherit slots with svelte components?

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

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> 

REPL

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM