Kurs Svelte i SvelteKit · Moduł 3: Reaktywność i runy
Porównanie: Stara vs Nowa składnia
W tej lekcji8
Zobaczmy jak stara składnia Svelte 4 przekłada się na Runes w Svelte 5. Starą składnię spotkasz w istniejących projektach i starszych poradnikach, dlatego warto ją rozpoznawać - ale nowy kod pisz runami. W każdej parze najpierw jest Svelte 4 (legacy), a pod nim Svelte 5.
Stan
<!-- Svelte 4 (legacy) -->
<script>
let count = 0;
let items = [];
</script><!-- Svelte 5 z Runes -->
<script>
let count = $state(0);
let items = $state([]);
</script>Reaktywne deklaracje
<!-- Svelte 4 (legacy) -->
<script>
let count = 0;
$: doubled = count * 2;
$: tripled = count * 3;
$: total = doubled + tripled;
</script><!-- Svelte 5 z Runes -->
<script>
let count = $state(0);
let doubled = $derived(count * 2);
let tripled = $derived(count * 3);
let total = $derived(doubled + tripled);
</script>Reaktywne instrukcje
<!-- Svelte 4 (legacy) -->
<script>
let count = 0;
$: console.log('Count:', count);
$: {
if (count > 10) {
alert('Dużo!');
}
}
</script><!-- Svelte 5 z Runes -->
<script>
let count = $state(0);
$effect(() => {
console.log('Count:', count);
});
$effect(() => {
if (count > 10) {
alert('Dużo!');
}
});
</script>Props
<!-- Svelte 4 (legacy) -->
<script>
export let name;
export let count = 0;
</script><!-- Svelte 5 z Runes -->
<script>
let { name, count = 0 } = $props();
</script>Bindable props
Komponent Input.svelte oddaje wpisaną wartość rodzicowi przez bind:value:
<!-- Svelte 4 (legacy) -->
<script>
export let value;
</script>
<input bind:value><!-- Svelte 5 z Runes -->
<script>
let { value = $bindable() } = $props();
</script>
<input bind:value>Użycie u rodzica wygląda w obu wersjach tak samo:
<script>
import Input from './Input.svelte';
let myValue = $state('');
</script>
<Input bind:value={myValue} />
<p>Wpisano: {myValue}</p>Zdarzenia
<!-- Svelte 4 (legacy) -->
<script>
let count = 0;
</script>
<button on:click={() => count++}>Kliknięto {count} razy</button><!-- Svelte 5 z Runes -->
<script>
let count = $state(0);
</script>
<button onclick={() => count++}>Kliknięto {count} razy</button>Kiedy używać którego?
| Sytuacja | Svelte 4 (legacy) | Svelte 5 Runes |
|---|---|---|
| Prosty stan | let x = 0 | let x = $state(0) |
| Obliczenie | $: y = x * 2 | let y = $derived(x * 2) |
| Efekt | $: { ... } | $effect(() => { ... }) |
| Props | export let | $props() |
| Zdarzenia DOM | on:click={fn} | onclick={fn} |
| Zdarzenia komponentu | createEventDispatcher | funkcje w props, np. onselect |
| Treść od rodzica | <slot /> | {@render children()} |
Tryb zgodności - komponent po komponencie
Svelte 5 wspiera obie składnie, ale nie w jednym pliku. Komponent, który użyje choćby jednej runy, działa w trybie run - wtedy $: i export let są w nim błędem kompilacji. Komponent bez run działa w trybie zgodności (legacy). Możesz więc migrować stopniowo, plik po pliku.
Stary komponent nadal działa bez zmian:
<!-- OldCounter.svelte - Svelte 4 (legacy) -->
<script>
let oldCount = 0;
$: oldDoubled = oldCount * 2;
</script>
<button on:click={() => oldCount++}>
Stary licznik: {oldCount} (x2 = {oldDoubled})
</button>Nowy komponent obok niego używa run:
<!-- NewCounter.svelte - Svelte 5 z Runes -->
<script>
let newCount = $state(0);
let newDoubled = $derived(newCount * 2);
</script>
<button onclick={() => newCount++}>
Nowy licznik: {newCount} (x2 = {newDoubled})
</button>A rodzic używa obu, jakby nic się nie stało:
<!-- App.svelte -->
<script>
import OldCounter from './OldCounter.svelte';
import NewCounter from './NewCounter.svelte';
</script>
<OldCounter />
<NewCounter />Gdy zechcesz przenieść cały projekt na runy, pomoże polecenie npx sv migrate svelte-5 - przepisze większość kodu automatycznie.
Wybierz Runes dla nowych projektów - to teraźniejszość i przyszłość Svelte!
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. Jaki jest odpowiednik starego $: doubled = count * 2 w Svelte 5?
2. Jak wygląda nowy odpowiednik 'export let name' w Svelte 5?