Теперь, когда Svelte 5 находится в предварительной версии, я чувствую, что могу выразить некоторую путаницу по поводу слотов в Svelte 5. В Svelte 4 слоты и названия слотов сделаны следующим образом:
ContactCard.svelte
<article class = "contact-card">
<h2>
<slot name = "name">
<span class = "missing">Unknown name</span>
</slot>
</h2>
<div class = "address">
<slot name = "address">
<span class = "missing">Unknown address</span>
</slot>
</div>
<div class = "email">
<slot name = "email">
<span class = "missing">Unknown email</span>
</slot>
</div>
</article>
<style>...</style>
+page.svelte
<script>
import ContactCard from './ContactCard.svelte';
</script>
<ContactCard>
<span slot = "name"> P. Sherman </span>
<span slot = "address">
42 Wallaby Way<br />
Sydney
</span>
</ContactCard>
По моему скромному мнению, довольно просто и понятно.
Component.svelte
<script>
let { children } = $props();
</script>
<div>
{@render children()}
</div>
+page.svelte
<script>
import { Component } from '$lib';
</script>
<Component>
...content...
</Component>
Также легко...
Как нам реализовать «именованные слоты» в этой новой парадигме?
🤔 А знаете ли вы, что...
JavaScript позволяет создавать мобильные приложения для iOS и Android с использованием фреймворков, таких как React Native и NativeScript.
Вы просто определяете #snippet
внутри компонента.
Фрагмент будет передан как реквизит с тем же именем. Например.:
<script>
import ContactCard from './ContactCard.svelte';
</script>
<ContactCard>
{#snippet name()} P. Sherman {/snippet}
{#snippet address()}
42 Wallaby Way <br>
Sydney
{/snippet}
</ContactCard>
(Если вам нужны элементы span
, вы можете добавить их внутрь фрагмента.)
<!-- ContactCard.svelte -->
<script>
let { name, address } = $props();
</script>
<div>
<div class = "name">{@render name()}</div>
<div class = "address">{@render address()}</div>
</div>
Для резервного контента вы можете проверить, был ли передан фрагмент, например. используя {#if}
, или определите резервный фрагмент.
<div class = "name">
{@render name?.()}
{#if !name}
...
{/if}
</div>
<div class = "name">
{#snippet nameUnknown()}...{/snippet}
{@render (name ?? nameUnknown)()}
</div>
Фрагменты могут быть определены вне компонента, а также переданы явно:
{#snippet name()} P. Sherman {/snippet}
{#snippet address()}
42 Wallaby Way <br>
Sydney
{/snippet}
<ContactCard {name} {address} />
Определение области действия работает аналогично переменным; фрагменты доступны на том же уровне и глубже в своем элементе/блоке.
Примечание: прямое содержимое компонента просто неявно определяет фрагмент под названием children
. Если вам нужно параметризовать фрагмент, вам также придется определить его более явно, например:
<FancyList items = {users}>
{#snippet children(item)}
{item.lastName}, {item.firstName}
{/snippet}
</FancyList>
На этом этапе вы также можете назвать это как-нибудь более конкретно, например itemTemplate
в этом примере.