We've learned how to use slot in @sveltejs , now let's see how we can pass dynamic data to the slotted contents
<Component>
<div>i want {dynamic} {data}!</div>
</Component>
This article is a summary from my video from the "Svelte 101" series, "Passing data across slot"
If you prefer video, check it out for a detailed walkthrough!
When you use a slot, data in the slotted content can come from 2 components:
- the current component (A)
- the component we are using (B)
<!-- filename: A.svelte -->
<B>
<div>i want {dynamic} {data}!</div>
</B>
1. Passing data from the current component
Passing data from the current component (A) is what we've always do:
- define the variable in the script tag
- use it
<!-- filename: A.svelte -->
<script>
let dataFromA = 'dynamic';
</script>
<B>
<div>i want {dataFromA} {data}!</div>
</B>
2. Passing data from the component you are using
Passing data from the component (B) however, require us to pass the data as props to the slot
<!-- filename: B.svelte -->
<script>
let dataFromB = 'data';
</script>
<slot dataFromB={dataFromB} />
<!-- or using shorthand: -->
<slot {dataFromB} />
And to receives it, you create what we called a let:
binding
<!-- filename: A.svelte -->
<script>
let dataFromA = 'dynamic';
</script>
<B let:dataFromB>
<div>i want {dataFromA} {dataFromB}!</div>
</B>
- You starts with
let:
+ props name passed to the slot - The props name variable will then be available to your slotted content
- The let binding creates a new scope to the elements beneath to access the props variable
You can rename the props name as you need
<!-- filename: A.svelte -->
<script>
let dataFromA = 'dynamic';
</script>
<B let:dataFromB={somethingElse}>
<div>i want {dataFromA} {somethingElse}!</div>
</B>
This is especially useful when the prop name shadows the variable from the outer scope, and you want to access both the variables:
<!-- filename: A.svelte -->
<script>
let data = 'from a';
</script>
<B let:data={dataFromB}>
<div>data from A: {data}</div>
<div>data from B: {dataFromB}</div>
</B>
Slot props for named slots
Remember named slots?
You can choose to pass different data for different slotted content!
<!-- filename: B.svelte -->
<script>
let title = "Passing data to slot";
let content = "Svelte is fun!";
</script>
<slot name="header" {title} />
<slot name="body" {content} />
<!-- filename: A.svelte -->
<B>
<svelte:fragment slot="header" let:title>
<h1>{title}</h1>
</svelte:fragment>
<svelte:fragment slot="body" let:content>
<div>{content}</div>
</svelte:fragment>
</B>
Reactive data
Well, the let:
binding is not 2-way, (not for now π)
To pass data back to the component B, you'll need a callback function
<!-- filename: B.svelte -->
<script>
let dataFromB = 'data';
function updateData(newData) {
dataFromB = newData;
}
</script>
<slot {dataFromB} {updateData} />
<!-- filename: A.svelte -->
<B let:dataFromB let:updateData>
<div>i want {dataFromB}!</div>
<button on:click={() => {
updateData(123);
}}>Click Me</button>
</B>
Well, an alternative to callback function would be using a store, however using $
for a store that is not declared at the top-level of the script is not supported yet!
...and the workaround doesn't seem better to me π
<!-- filename: A.svelte -->
<B let:dataFromB>
<!-- β οΈ Stores must be declared at the top level of the component (this may change in a future version of Svelte) -->
<div>i want {$dataFromB}!</div>
<button on:click={() => { $dataFromB = 123; }}>
Click Me
</button>
</B>
<!-- Workaround -->
<script>
import { get } from 'svelte/store';
</script>
<B let:dataFromB>
<div>i want {get(dataFromB)}!</div>
<button on:click={() => { dataFromB.set(123); }}>
Click Me
</button>
</B>
Reference
- Svelte tutorial: Slot props https://svelte.dev/tutorial/slot-props
Top comments (2)
Hello, if you want to play on what a cool site to play online you definitely need to try to play here in the UK Empire Casino, it really is a fantastic site to play online, it's great to know that you can play on something so high quality, with deposit bonuses now is the best option to play even outside our country
Oh yes, this is incredible and exactly what I needed π₯³ thanks a lot π