Table Of Contents
Composition is a powerful tool that allows you to create complex application functionality by combining small and easily manageable components. To achieve composition in Svelte 3, you have to use a slot directive.
Slots
As a normal html element, a svelte 3 component can have some child content.You can pass any valid html data inside a component, and it will be rendered inside a slot directive:
Box.svelte
<style>
.box {
width: 250px;
border: 1px solid #aaa;
padding: 1em;
margin: 1em;
display: inline-block;
}
</style>
<div class="box">
<slot></slot>
</div>
<script>
import Box from "./Box.svelte";
</script>
<Box>
<h1>Hello World</h1>
<p>Some paragraf</p>
</Box>
As the result you will have a box with a header and paragraph inside of a box.
Slot fallback
Slot allows you to define some custom content that will be shown if there is no child content:
SlotWithFallback.svelte
<slot>
<h2>There is no child content!</h2>
</slot>
App.svelte
<script>
import SlotWithFallback from "./SlotWithFallback.svelte";
</script>
<!-- will render h1 and p -->
<SlotWithFallback>
<h1>Hello World</h1>
<p>Some paragraf</p>
</SlotWithFallback>
<!-- will render <h2>There is no child content!</h2> -->
<SlotWithFallback />
Named slots
Sometimes you will need to target different slots inside the same component. You can do this by adding names to slots:
NamedBox.svelte
<style>
.box {
width: 250px;
border: 1px solid #aaa;
padding: 1em;
margin: 1em;
display: inline-block;
}
</style>
<div class="box">
<slot name="top"></slot>
<hr />
<slot name="bottom"></slot>
</div>
App.svelte
<script>
import NamedBox from "./NamedBox.svelte";
</script>
<!-- will render h1 in top slot and p in bottom slot -->
<NamedBox>
<h1 slot="top">Title</h1>
<p slot="bottom">Paragraph</p>
</NamedBox>
Slot props
In Svelte 3 you can also reference variables of parent component. Let's create a box with a secret content that can be toggled using checkbox:
Secret.svelte
<script>
let showSecret = false;
</script>
<label>
<input type="checkbox" bind:checked={showSecret} />
Show secret
</label>
<slot showSecret={showSecret}></slot>
App.svelte
<script>
import Secret from "./Secret.svelte";
</script>
<Secret let:showSecret={isSecretShown}>
{#if isSecretShown}
<p>Hello world!</p>
{:else}
<p>***********</p>
{/if}
</Secret>
In the example above we are referencing showSecret as isSecretShown (let:showSecret={isSecretShown}) and now we can use it as a variable. Personaly, I've found a bit stange the syntax, but I think you should understand it better this way: (expose)let:(property)showSecret={(as)isSecretShown}.
Top comments (0)