Kurs Svelte i SvelteKit · Moduł 2: Komponenty
Specjalne elementy Svelte
W tej lekcji6
Svelte oferuje specjalne elementy do obsługi zaawansowanych przypadków. Zanim je poznasz - dwie sztuczki, do których w Svelte 4 potrzebne były specjalne elementy, a w Svelte 5 działają zwykłe komponenty.
Rekurencja - komponent importuje sam siebie
Komponent może renderować sam siebie. W Svelte 5 po prostu importuje własny plik:
<!-- TreeNode.svelte - Gałęzie Yggdrasil -->
<script>
import TreeNode from './TreeNode.svelte';
let { node, depth = 0 } = $props();
</script>
<div class="node" style="margin-left: {depth * 20}px">
<span>{node.name}</span>
{#if node.children}
{#each node.children as child}
<TreeNode node={child} depth={depth + 1} />
{/each}
{/if}
</div>
<style>
.node {
padding: 0.5rem;
border-left: 2px solid #4a7c23;
}
</style>Użycie:
<script>
import TreeNode from './TreeNode.svelte';
const yggdrasil = {
name: 'Yggdrasil',
children: [
{ name: 'Asgard', children: [{ name: 'Walhalla' }] },
{ name: 'Midgard', children: [{ name: 'Svenheim' }] },
{ name: 'Niflheim' }
]
};
</script>
<TreeNode node={yggdrasil} />W Svelte 4 używano do tego elementu <svelte:self>. W Svelte 5 jest przestarzały - komponent importuje sam siebie.
Dynamiczny komponent
W Svelte 5 komponenty są dynamiczne same z siebie: jeśli zmienna z komponentem się zmieni, Svelte wyrenderuje nowy. Wystarczy zapisać komponent w zmiennej, której nazwa zaczyna się wielką literą, i użyć jej jak znacznika:
<script>
import Warrior from './Warrior.svelte';
import Ship from './Ship.svelte';
import Treasure from './Treasure.svelte';
const components = {
warrior: Warrior,
ship: Ship,
treasure: Treasure
};
let selected = $state('warrior');
let Selected = $derived(components[selected]);
</script>
<select bind:value={selected}>
<option value="warrior">Wojownik</option>
<option value="ship">Statek</option>
<option value="treasure">Skarb</option>
</select>
<Selected />W Svelte 4 trzeba było pisać <svelte:component this={...} />. W Svelte 5 ten element jest przestarzały.
svelte:element - Dynamiczny element HTML
<script>
let { level = 1, text } = $props();
// h1, h2, h3... dynamicznie
let tag = $derived(`h${Math.min(level, 6)}`);
</script>
<svelte:element this={tag}>
{text}
</svelte:element>svelte:window - Zdarzenia okna
Do okna przeglądarki podpinasz zdarzenia tak samo jak do zwykłych elementów - atrybutami, np. onkeydown. Wiązania bind: potrzebują zmiennych z $state:
<script>
let innerWidth = $state(0);
let innerHeight = $state(0);
let scrollY = $state(0);
function handleKeydown(event) {
if (event.key === 'Escape') {
console.log('Naciśnięto Escape!');
}
}
</script>
<svelte:window
bind:innerWidth
bind:innerHeight
bind:scrollY
onkeydown={handleKeydown}
/>
<p>Rozmiar okna: {innerWidth} x {innerHeight}</p>
<p>Scroll: {scrollY}px</p>svelte:document i svelte:body
<script>
function handleVisibility() {
console.log('Widoczność karty:', document.visibilityState);
}
function handleMouseEnter() {
console.log('Kursor wrócił na stronę');
}
</script>
<svelte:document onvisibilitychange={handleVisibility} />
<svelte:body onmouseenter={handleMouseEnter} />svelte:head - Meta w head
<script>
let { title = 'Kraina Wikingów' } = $props();
</script>
<svelte:head>
<title>{title}</title>
<meta name="description" content="Nauka Svelte w krainie wikingów" />
</svelte:head>Specjalne elementy to runy mocy na wyjątkowe okazje - sięgaj po nie, gdy zwykły HTML nie wystarcza.
Hasła z dokumentacji w tej lekcji
Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Jak w Svelte 5 komponent może renderować sam siebie (rekurencja)?
2. Jak w Svelte 5 wyrenderować komponent zapisany w zmiennej?
3. Którego specjalnego elementu używamy do modyfikacji sekcji <head> strony?
Zadania praktyczne w grze
- Edytor kodu
Uzupełnij kod, aby nasłuchiwać na zdarzenie keydown