Svelte 5 führt neue Runen-API ein

Seite 3: Svelte 5 bringt weitere Änderungen

Inhaltsverzeichnis

Runes sind sicherlich die größte Änderung, die uns in Svelte 5 erwartet. Daneben gibt es weitere Änderungen, die darauf abzielen, die Anzahl an Konzepten, die es zu lernen gilt, zu reduzieren und gleichzeitig die Flexibilität des JavaScript-Frameworks zu erhöhen.

Die erste dieser Änderungen sind Event Attributes. Bisher wurden Events in Svelte durch ein on:-Prefix definiert:

<!-- HTML-Element -->
<button on:click={() => ..}>click me</button>
<!-- Komponente -->
<Button on:click={() => ..}>click me</Button>

Zwar lässt das on:-Präfix sofort erkennen, dass es sich um ein Event handelt, jedoch hat diese Lösung einige Nachteile, die sich gerade beim Erstellen von Komponenten zeigen:

  • Events nach oben durchzureichen, ist mühsam. Es ist nicht möglich, Svelte zu sagen "reiche einfach alle Events dieses Elements an meine Verwenderkomponente weiter", stattdessen müssen Entwicklerinnen und Entwickler jedes einzeln explizit weitergeben.
  • Komponenten-Events zu definieren, ist umständlich. Man muss createEventDispatcher nutzen und Events darüber anstoßen. Diese Events sind vom Typ CustomEvent, daher müssen Verwender event.detail schreiben, nur um an den eigentlichen Payload zu kommen.
  • Komponenten-Events lassen sich auch als Callback-Properties definieren, was bedeutet, dass es zwei Wege gibt, die gleiche Sache zu tun.

Event Attributes lösen alle diese Probleme. Statt on:click schreibt man onclick – sprich, alle DOM-Attribute, die mit on beginnen, sind Events. Dadurch lassen sie sich auf der Ebene der Komponenten wie Properties behandeln und entsprechend einfach durchreichen. Das sieht dann etwa so aus:

<script>
	let { onclick, onHello, ...rest } = $props();
</script>

<!-- onclick callback prop an den Button weitergeben -->
<button {onclick}>click me</button>
<!-- alle sonstigen Properties an den Button weitergeben –  alle on-Properties
     sind Events, auf die gehört wird -->
<button {...rest}>click me</button>
<!-- eigene Events per Callback Props aufrufen -->
<button onclick={() => onHello('hello!')}>click me</button>

Wer bereits JSX-Frameworks wie React benutzt hat, wird sich mit Callback-Properties direkt wie zu Hause fühlen. Der einzige Unterschied zu React ist, dass die DOM-Events in Svelte komplett kleingeschrieben werden, also onclick statt onClick.

Eine weitere Neuerung sind Snippets. Sie ermöglichen es, kleine wiederverwendbare UI-Schnipsel zu definieren und an verschiedenen Stellen zu verwenden. Sie sind wie der kleine Bruder einer Komponente: Schneller erstellt, fokussiert auf UI-Wiederverwendung, dafür weniger mächtig. Ein Snippet wird folgendermaßen definiert:

{#snippet snippetWithoutArgument()}
	<p>hello world</p>
{/snippet}
{#snippet snippetWithArgument(name)}
	<p>hello {name}</p>
{/snippet}

Sie lassen sich mithilfe des @render-Tags rendern:

{@render snippetWithoutArgument()}
{@render snippetWithArgument('Svelte')}

Snippets lassen sich nicht nur innerhalb derselben Komponente rendern, in der sie definiert sind, sie lassen sich auch als Properties an eine Komponente weiterreichen:

<!-- Verwender: -->
{#snippet row(item)}
	<span>{item}</span>
{/snippet}

<List list={..} {row} />

<!-- List.svelte: -->
<script>
	let { row, list } = $props();
</script>

<ul>
	{#each list as item}
		<li>{@render row(item)}</li>
	{/each}
</ul>

Wenn das Snippet nur für diese Komponente gedacht ist, kann als Kurzschreibweise das Snippet innerhalb der Komponente definiert werden. Damit wird das Snippet implizit als Property desselben Namens in die Komponente hineingereicht.

<!-- Äquivalent zu obigem Code: -->
<List list={..}>
	{#snippet row(item)}
		<span>{item}</span>
	{/snippet}
</List>

Somit sind Snippets also nicht nur ein neues Feature zum Definieren wiederverwendbarer UI-Elemente, sie agieren zugleich als bessere Version der Slot-API. Statt let:x={y}[code], [code]<slot name="..">, <svelte:fragment>, $$slots und vielen weiteren umständlichen Bestandteilen der Slot-API kommen nun Snippets zum Einsatz, die leichter zu erlernen und zu verstehen sind und zugleich mehr Flexibilität und Möglichkeiten bieten.

Runes, Event Attributes und Snippets sind bedeutende Änderungen an der Svelte-API. Nicht jedes Projekt kann jedoch in einem Rutsch auf die neue Syntax umstellen. Daher ist das Svelte-Team sehr darauf bedacht, das Upgrade auf Svelte 5 so reibungslos wie möglich zu gestalten. Konkret bedeutet das: Die komplette API, die wir aus Svelte 4 kennen, funktioniert auch in Svelte 5. Event Attributes lassen sich Seite an Seite mit den bisherigen Events verwenden, ebenso Slots und Snippets. Lediglich Runes sind pro Komponente exklusiv: Wer eine Rune benutzt, kann die alte Syntax wie etwa $: und export let nicht mehr in dieser Komponente nutzen.

Komponenten, die Runes nutzen, können jedoch ohne Problem Komponenten verwenden, die noch keine Runes nutzen, und umgekehrt. Das ist besonders hilfreich, da es wahrscheinlich etwas Zeit braucht, bis alle Svelte-Libraries auf die neue Syntax umgestellt sind. Das Svelte-Entwicklerteam hofft, dass Entwicklerinnen und Entwickler dann für die meisten Apps nicht mehr als eine Handvoll Zeilen Code ändern müssen, wenn sie auf die neue Version upgraden.

Momentan plant das Svelte-Team, die alten APIs in Svelte 5 und 6 weiterhin zu unterstützen und in Svelte 7 zu entfernen. Das sollte allen Projekten genügend Zeit geben, sich anzupassen.