Svelte组件如何转发插槽并使用原组件的插槽回退内容?
解决Svelte封装组件时复用原组件插槽回退内容的问题
问题原因
当封装组件(比如AnonCard基于Card)时,直接通过<slot name="xxx" />转发插槽,若父组件未提供对应插槽内容,封装组件会向原组件传递一个空插槽,覆盖原组件的回退内容,导致原组件的默认值无法显示。
解决方案
利用Svelte内置的$$slots对象判断当前组件是否接收到对应具名插槽的内容,仅当插槽存在时才转发给原组件,否则让原组件的回退内容生效。
原组件(Card.svelte)
<div class="card"> <div class="name"> <slot name="name">Unknown Name</slot> </div> <div class="phone"> <slot name="phone">No Phone Provided</slot> </div> </div>
修改后的封装组件(AnonCard.svelte)
<script> import Card from './Card.svelte'; </script> <Card> {#if $$slots.name} <slot name="name" /> {/if} {#if $$slots.phone} <slot name="phone" /> {/if} </Card>
父组件使用示例(App.svelte)
<script> import AnonCard from './AnonCard.svelte'; </script> <!-- 仅传递phone插槽,name自动使用Card的回退内容 --> <AnonCard> <svelte:fragment slot="phone">123-456-7890</svelte:fragment> </AnonCard> <!-- 传递两个插槽,覆盖原回退内容 --> <AnonCard> <svelte:fragment slot="name">John Doe</svelte:fragment> <svelte:fragment slot="phone">987-654-3210</svelte:fragment> </AnonCard> <!-- 不传递任何插槽,完全复用Card的回退内容 --> <AnonCard />
原理说明
$$slots是Svelte提供的特殊只读对象,其键为当前组件接收到的具名插槽名称。通过{#if $$slots.xxx}判断插槽是否存在,仅在存在时才转发给原组件,原组件在未收到对应插槽时会自动显示自身定义的回退内容。
内容的提问来源于stack exchange,提问作者opensas
相关产品推荐
相关产品推荐

