Svelte ist ein relativ neues UI-Framework, das von Rich Harris entwickelt wurde , der auch der Autor des Rollup-Builders ist. Höchstwahrscheinlich wird Svelte völlig anders aussehen als das, was Sie zuvor behandelt haben, aber vielleicht ist das sogar gut. Die beiden beeindruckendsten Merkmale dieses Frameworks sind Geschwindigkeit und Einfachheit. In diesem Artikel konzentrieren wir uns auf die zweite.

Da meine Hauptentwicklungserfahrung mit Angular zusammenhängt, versuche ich natürlich, Svelte zu lernen, indem ich die mir bereits bekannten Ansätze kopiere. Und genau darum geht es in diesem Artikel: Wie man in Svelte die gleichen Dinge macht wie in Angular.
Hinweis: Trotz der Tatsache, dass ich in einigen Fällen meine Präferenz ausdrücken werde, ist der Artikel kein Vergleich von Frameworks. Dies ist eine schnelle und einfache Einführung in Svelte für Personen, die Angular bereits als Hauptrahmen verwenden.
Warnung Spoiler: Svelte macht Spaß.
Komponenten
In Svelte ist jede Komponente der Datei zugeordnet, in die sie geschrieben wurde. Beispielsweise wird die Button
Komponente durch Benennen der Button.svelte
Datei erstellt. Natürlich machen wir das normalerweise auch in Angular, aber bei uns ist es nur eine Konvention. (In Svelte stimmt der Name der zu importierenden Komponente möglicherweise auch nicht mit dem Dateinamen überein - Hinweis des Übersetzers)
Svelte-Komponenten sind Einzeldateien und bestehen aus drei Abschnitten: script
, style
und eine Vorlage, die nicht in ein spezielles Tag eingeschlossen werden muss.
Lassen Sie uns eine sehr einfache Komponente erstellen, die "Hello World" anzeigt.

Komponenten importieren
Im Allgemeinen ähnelt dies dem Importieren einer JS-Datei, jedoch mit einigen Einschränkungen:
- Sie müssen die
.svelte
der .svelte
Komponente explizit angeben - Komponenten werden in das
<script>
importiert
<script> import Todo from './Todo.svelte'; </script> <Todo></Todo>
Aus den obigen Ausschnitten geht hervor, dass die Anzahl der Zeilen zum Erstellen einer Komponente in Svelte unglaublich gering ist. Natürlich gibt es einige Implizitäten und Einschränkungen, aber gleichzeitig ist alles einfach genug, um sich schnell daran zu gewöhnen.
Grundlegende Syntax
Interpolation
Interpolationen in Svelte sind denen in React ähnlicher als in Vue oder Angular:
<script> let someFunction = () => {...} </script> <span>{ 3 + 5 }</span> <span>{ someFunction() }</span> <span>{ someFunction() ? 0 : 1 }</span>
Ich bin es gewohnt, doppelte geschweifte Klammern zu verwenden, daher bin ich manchmal versiegelt, aber vielleicht habe ich nur dieses Problem.
Attribute
Das Übergeben von Attributen an Komponenten ist ebenfalls recht einfach. Anführungszeichen sind optional und es können beliebige Javascript-Ausdrücke verwendet werden:
//Svelte <script> let isFormValid = true; </script> <button disabled={!isFormValid}></button>
Ereignisse
Die Syntax für Ereignishandler lautet: on:={}
.
<script> const onChange = (e) => console.log(e); </script> <input on:input={onChange} />
Im Gegensatz zu Angular müssen wir keine Klammern nach dem Funktionsnamen verwenden, um ihn aufzurufen. Wenn Sie Argumente an den Handler übergeben müssen, verwenden Sie einfach die anonyme Funktion:
<input on:input={(e) => onChange(e, 'a')} />
Meine Ansicht zur Lesbarkeit eines solchen Codes:
- Wir müssen weniger drucken, weil wir keine Anführungszeichen und Klammern benötigen - das ist sowieso gut.
- Lesen Sie besser. Ich habe den Angular-Ansatz immer eher gemocht als reagiert, daher ist es für mich und Svelte schwieriger, ihn zu wählen. Aber das ist nur meine Gewohnheit und meine Meinung ist etwas voreingenommen.
Strukturrichtlinien
Im Gegensatz zu strukturierten Direktiven in Vue und Angular bietet Svelte eine spezielle Syntax für Schleifen und Verzweigungen in Vorlagen:
{#if todos.length === 0} {:else} {#each todos as todo} <Todo {todo} /> {/each} {/if}
Gefällt mir sehr. Es werden keine zusätzlichen HTML-Elemente benötigt, und in Bezug auf die Lesbarkeit sieht dies erstaunlich aus. Leider befindet sich das Symbol #
im britischen Tastaturlayout meines Macbooks an einer unzugänglichen Stelle, was sich negativ auf meine Erfahrung mit diesen Strukturen auswirkt.
Eingabeeigenschaften
Das Definieren von Eigenschaften, die an eine Komponente übergeben werden können (analog zu @Input
in Angular), ist so einfach wie das Exportieren einer Variablen aus einem JS-Modul mit dem Schlüsselwort export
. Vielleicht kann es zunächst verwirrend sein - aber lassen Sie uns ein Beispiel schreiben und sehen, wie einfach es wirklich ist:
<script> export let todo = { name: '', done: false }; </script> <p> { todo.name } { todo.done ? '✓' : '✕' } </p>
- Wie Sie sehen können, haben wir die
todo
Eigenschaft zusammen mit dem Wert initialisiert: todo
standardmäßig der Wert der Eigenschaft, falls sie nicht von der übergeordneten Komponente übergeben wird
Erstellen Sie nun einen Container für diese Komponente, der Daten an sie überträgt:
<script> import Todo from './Todo.svelte'; const todos = [{ name: " Svelte", done: false }, { name: " Vue", done: false }]; </script> {#each todos as todo} <Todo todo={todo}></Todo> {/each}
Ähnlich wie Felder in einem regulären JS-Objekt kann todo={todo}
wie folgt gekürzt und neu geschrieben werden:
<Todo {todo}></Todo>
Anfangs kam es mir seltsam vor, aber jetzt finde ich es genial.
Ausgabeeigenschaften
Um das Verhalten der @Output
Direktive zu implementieren, verwenden wir createEventDispatcher
die in Svelte verfügbare Funktion createEventDispatcher
, wenn die übergeordnete Komponente Benachrichtigungen vom createEventDispatcher
@Output
.
- Importieren Sie die Funktion
createEventDispatcher
und weisen Sie der createEventDispatcher
ihren Rückgabewert zu - Die
dispatch
hat zwei Parameter: den Namen des Ereignisses und die Daten (die in das detail
des Ereignisobjekts fallen) - Wir
markDone
dispatch
in die markDone
Funktion ein, die vom click-Ereignis aufgerufen wird ( on:click
).
<script> import { createEventDispatcher } from 'svelte'; export let todo; const dispatch = createEventDispatcher(); function markDone() { dispatch('done', todo.name); } </script> <p> { todo.name } { todo.done ? '✓' : '✕' } <button on:click={markDone}></button> </p>
In der übergeordneten Komponente müssen Sie einen Handler für das Ereignis done
erstellen, damit Sie die erforderlichen Objekte im todo
markieren können.
- Erstellen Sie die
onDone
Funktion - Wir weisen diese Funktion dem Ereignishandler zu, der in der
on:done={onDone}
Komponente wie folgt aufgerufen wird: on:done={onDone}
<script> import Todo from './Todo.svelte'; let todos = [{ name: " Svelte", done: false }, { name: " Vue", done: false }]; function onDone(event) { const name = event.detail; todos = todos.map((todo) => { return todo.name === name ? {...todo, done: true} : todo; }); } </script> {#each todos as todo} <Todo {todo} on:done={onDone}></Todo> {/each}
Hinweis: Um Änderungen an einem Objekt zu erkennen, wird das Objekt selbst nicht mutiert. Stattdessen weisen wir der Variablen todos
ein neues Array zu, in dem das Objekt der gewünschten Aufgabe bereits in "Abgeschlossen" geändert wird.
Daher wird Svelte als wirklich reaktiv angesehen : Bei der üblichen Zuweisung eines Werts zu einer Variablen ändert sich der entsprechende Teil der Darstellung.
ngModel
Svelte hat eine spezielle bind:<>={}
um bestimmte Variablen an die Attribute einer Komponente zu binden und miteinander zu synchronisieren.
Mit anderen Worten, Sie können die bidirektionale Datenbindung organisieren:
<script> let name = ""; let description = ""; function submit(e) { </script> <form on:submit={submit}> <div> <input placeholder="" bind:value={name} /> </div> <div> <input placeholder="" bind:value={description} /> </div> <button> </button> </form>
Reaktive Ausdrücke
Wie wir bereits gesehen haben, reagiert Svelte auf das Zuweisen von Werten zu Variablen und zeichnet die Ansicht neu. Sie können auch reaktive Ausdrücke verwenden, um auf Änderungen des Werts einer Variablen zu reagieren und den Wert einer anderen Variablen zu aktualisieren.
Erstellen wir beispielsweise eine Variable, die uns zeigen soll, dass im todos
Array alle Aufgaben als erledigt markiert sind:
let allDone = todos.every(({ done }) => done);
Die Ansicht wird jedoch nicht neu gezeichnet, wenn das Array aktualisiert wird, da der Wert der Variablen allDone
nur einmal zugewiesen wird. Wir werden einen reaktiven Ausdruck verwenden, der uns gleichzeitig an die Existenz von "Labels" in Javascript erinnert:
$: allDone = todos.every(({ done }) => done);
Es sieht sehr exotisch aus. Wenn es Ihnen so vorkommt, als gäbe es „zu viel Magie“, erinnere ich Sie daran, dass Tags gültiges Javascript sind .
Eine kleine Demo, die das oben Genannte erklärt:

Inhaltsinjektion
Zum Einbetten von Inhalten werden auch Slots verwendet, die an der richtigen Stelle innerhalb der Komponente platziert werden.
Um einfach den Inhalt anzuzeigen, der innerhalb des Komponentenelements übertragen wurde, wird ein spezielles slot
Element verwendet:
// Button.svelte <script> export let type; </script> <button class.type={type}> <slot></slot> </button> // App.svelte <script> import Button from './Button.svelte'; </script> <Button> </Button>
In diesem Fall ersetzt die ""
das Element <slot></slot>
.
Benannte Slots müssen benannt werden:
// Modal.svelte <div class='modal'> <div class="modal-header"> <slot name="header"></slot> </div> <div class="modal-body"> <slot name="body"></slot> </div> </div> // App.svelte <script> import Modal from './Modal.svelte'; </script> <Modal> <div slot="header"> </div> <div slot="body"> </div> </Modal>
Lebenszyklus-Haken
Svelte bietet 4 Lifecycle-Hooks an, die aus dem svelte
Paket importiert werden.
- onMount - Wird aufgerufen, wenn eine Komponente im DOM bereitgestellt wird
- beforeUpdate - wird vor dem Aktualisieren der Komponente aufgerufen
- afterUpdate - wird nach der Komponentenaktualisierung aufgerufen
- onDestroy - wird aufgerufen, wenn eine Komponente aus dem DOM entfernt wird
Die onMount
Funktion verwendet als Parameter eine Rückruffunktion, die aufgerufen wird, wenn die Komponente im DOM platziert wird. Einfach ausgedrückt ähnelt es der Hook- ngOnInit
.
Wenn die Rückruffunktion eine andere Funktion zurückgibt, wird sie aufgerufen, wenn die Komponente aus dem DOM entfernt wird.
<script> import { onMount, beforeUpdate, afterUpdate, onDestroy } from 'svelte'; onMount(() => console.log('', todo)); afterUpdate(() => console.log('', todo)); beforeUpdate(() => console.log(' ', todo)); onDestroy(() => console.log('', todo)); </script>
Es ist wichtig zu onMount
dass beim Aufrufen von onMount
alle darin enthaltenen Eigenschaften bereits initialisiert sein müssen. Das heißt, im obigen Fragment sollte todo
bereits existieren.
Staatsverwaltung
Die Verwaltung Ihres Staates in Svelte ist unglaublich einfach, und vielleicht sympathisiert dieser Teil des Frameworks mehr als jeder andere mit mir. Sie können die Ausführlichkeit von Code vergessen, wenn Sie Redux verwenden. Zum Beispiel erstellen wir in unserer Anwendung Speicher für die Speicherung und Aufgabenverwaltung.
Aufzeichnbare Tresore
Zuerst müssen Sie das writable
Speicherobjekt aus dem svelte/store
Paket importieren und ihm den Anfangswert initialState
import { writable } from 'svelte/store'; const initialState = [{ name: " Svelte", done: false }, { name: " Vue", done: false }]; const todos = writable(initialState);
Normalerweise todos.store.js
ich ähnlichen Code in eine separate Datei wie todos.store.js
und exportiere die Speichervariable daraus, damit die Komponente, in die ich sie importiere, damit arbeiten kann.
Offensichtlich ist das todos
Objekt jetzt ein Repository geworden und kein Array mehr. Um den Speicherwert zu erhalten, verwenden wir in Svelte ein wenig Magie:
- Durch Hinzufügen des Zeichens
$
zum Namen der Speichervariablen erhalten wir direkten Zugriff auf ihren Wert!
Daher ersetzen wir im Code einfach alle Verweise auf die Variable todos
durch $todos
:
{#each $todos as todo} <Todo todo={todo} on:done={onDone}></Todo> {/each}
Statuseinstellung
Der neue Wert des beschreibbaren Speichers kann durch Aufrufen der set
Methode angegeben werden, die den Status unbedingt entsprechend dem übergebenen Wert ändert:
const todos = writable(initialState); function removeAll() { todos.set([]); }
Statusaktualisierung
Um den Speicher (in unserem Fall todos
) basierend auf seinem aktuellen Status zu update
, müssen Sie die update
aufrufen und eine Rückruffunktion übergeben, die den neuen Status für den Speicher zurückgibt.
Wir schreiben die zuvor erstellte onDone
Funktion neu:
function onDone(event) { const name = event.detail; todos.update((state) => { return state.map((todo) => { return todo.name === name ? {...todo, done: true} : todo; }); }); }
Hier habe ich einen Reduzierer direkt in der Komponente verwendet, was eine schlechte Praxis ist. Wir verschieben es in eine Datei mit unserem Repository und exportieren eine Funktion daraus, die einfach den Status aktualisiert.
Abonnement zur Statusänderung
Um festzustellen, dass sich der Wert im Repository geändert hat, können Sie die Methode subscribe
verwenden. Beachten Sie, dass das Repository kein observable
Objekt ist, sondern eine ähnliche Schnittstelle bietet.
const subscription = todos.subscribe(console.log); subscription();
Observables
Wenn dieser Teil Sie am meisten aufgeregt hat, dann beeile ich mich, dass Svelte vor nicht allzu langer Zeit RxJS-Unterstützung hinzugefügt und Observable for ECMAScript eingeführt wurde.
Als Angular-Entwickler bin ich bereits daran gewöhnt, mit reaktiver Programmierung zu arbeiten, und das Fehlen eines Gegenstücks zur asynchronen Pipe wäre äußerst unpraktisch. Aber auch hier hat mich Svelte überrascht.
Schauen wir uns ein Beispiel für die Zusammenarbeit dieser Tools an: Zeigen Sie eine Liste der Repositorys in Github an, die unter dem Schlüsselwort "Svelte"
.
Sie können den folgenden Code kopieren und direkt in der REPL ausführen:
<script> import rx from "https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"; const { pluck, startWith } = rx.operators; const ajax = rx.ajax.ajax; const URL = `https://api.github.com/search/repositories?q=Svelte`; const repos$ = ajax(URL).pipe( pluck("response"), pluck("items"), startWith([]) ); </script> {#each $repos$ as repo} <div> <a href="{repo.url}">{repo.name}</a> </div> {/each}
Fügen Sie einfach das $
-Symbol zum Namen der beobachtbaren Variablen repos$
und Svelte zeigt automatisch den Inhalt an.
Meine Wunschliste für Svelte
Typoskript-Unterstützung
Als Typescript-Enthusiast kann ich mir nur die Möglichkeit wünschen, Typen in Svelte zu verwenden. Ich bin so daran gewöhnt, dass ich manchmal mitgerissen werde und Typen in meinem Code anordne, die ich dann entfernen muss. Ich hoffe wirklich, dass Svelte bald Unterstützung für Typescript hinzufügen wird. Ich denke, dieser Artikel wird auf der Wunschliste von jedem stehen, der Svelte mit Erfahrung mit Angular verwenden möchte.
Vereinbarungen und Richtlinien
Das Rendern in der Darstellung einer Variablen aus dem <script>
-Block ist eine sehr leistungsstarke Funktion des Frameworks, kann aber meiner Meinung nach zu Code-Unordnung führen. Ich hoffe, dass die Svelte-Community eine Reihe von Konventionen und Richtlinien durcharbeitet, um Entwicklern beim Schreiben von sauberem und verständlichem Komponentencode zu helfen.
Unterstützung durch die Gemeinschaft
Svelte ist ein grandioses Projekt, das mit zunehmendem Aufwand der Community beim Schreiben von Paketen, Handbüchern, Blog-Artikeln und vielem mehr von Drittanbietern zu einem anerkannten Werkzeug in der erstaunlichen Welt der Frontend-Entwicklung werden kann, die wir heute haben.
Abschließend
Trotz der Tatsache, dass ich kein Fan der vorherigen Version des Frameworks war, machte Svelte 3 einen guten Eindruck auf mich. Es ist einfach, klein, kann aber viel. Es ist so anders als alles andere, dass es mich an die Aufregung erinnerte, die ich erlebte, als ich von jQuery zu Angular wechselte.
Unabhängig davon, welches Framework Sie gerade verwenden, dauert das Erlernen von Svelte wahrscheinlich nur einige Stunden. Sobald Sie die Grundlagen gelernt und die Unterschiede zu dem, was Sie an Schreiben gewöhnt sind, verstanden haben, wird die Arbeit mit Svelte sehr einfach.
Im russischsprachigen Telegrammkanal @sveltejs finden Sie sicherlich Entwickler, die Erfahrung mit verschiedenen Frameworks haben und bereit sind, ihre Geschichten, Gedanken und Tipps zu Svelte zu teilen.