Leichter und schneller – Ein Leitfaden für das Svelte Framework
Veröffentlicht: 2022-03-11Webanwendungen werden von Tag zu Tag beliebter. Sie sind eine wachsende Welt, die Menschen wegen ihrer Einfachheit, Geschwindigkeit und plattformübergreifenden Verfügbarkeit wählen. Single Page Applications (SPAs) haben an diesem Prozess eine große Rolle gespielt. Frameworks wie Angular, Vue.js und React helfen Entwicklern, in kurzer Zeit die beste Benutzererfahrung zu liefern, wobei der Code unterstützt und erweiterbar bleibt. Diese Tools sind in der Branche seit langem am beliebtesten, mit vielen Vorteilen gegenüber den neu erstellten Paketen. Es hat sich wie ein Oligopol in der SPA-Welt angefühlt. Eine Gruppe zukunftsorientierter Entwickler, die auf diesen Markt abzielen, könnte jedoch mit einem ernsthaften Konkurrenten – Svelte – einsteigen.
Svelte ist ein neuer Ansatz zum Erstellen von Benutzeroberflächen. Lassen Sie uns eintauchen und herausfinden, was es so frisch macht, indem wir ein gemeinsames Anmeldeformular erstellen.
Die Architektur
Svelte ist so konzipiert, dass es schneller ist als jede andere Bibliothek. Dies wird erreicht, indem der Schritt des Ladens eines Frameworks zum Erstellen eines virtuellen DOM verschoben wird. Anstatt während des laufenden Prozesses ein Tool zu verwenden, wird es in der Erstellungsphase in Vanilla JS kompiliert, sodass die Anwendung zum Starten keine Abhängigkeiten benötigt.
Schlank | Andere SPA-Bibliotheken (React, Vue.js, Angular usw.) |
---|---|
1. Öffnen Sie eine Website | 1. Öffnen Sie eine Website |
Die obige Tabelle beschreibt, warum Svelte ein absoluter Gewinner in Sachen Startleistung ist. Das wird nicht durch irgendeine Optimierung erreicht, sondern durch die Verwendung des verfügbaren Browser-JavaScript-Compilers anstelle eines Seitencompilers.
Installation
Die schlanke Installation ist unglaublich einfach und macht die Verwendung sehr angenehm. Der erste Schritt besteht darin, die Vorlage des Projekts herunterzuladen:
npx degit sveltejs/template svelte-login-form
Das Ausführen des obigen Befehls bedeutet, dass wir eine Svelte-Projektvorlage haben. Es ist im Moment leer und die erforderlichen NPM-Pakete sind noch nicht installiert. Lassen Sie uns das beheben.
cd svelte-login-form npm install
Jetzt ist die Anwendung startbereit, indem Sie den folgenden Befehl verwenden:
npm run dev
Struktur
Jede Svelte-Komponente kann die folgenden Abschnitte enthalten:
- Skript
- Stil
- Vorlage
Sehen wir uns das Beispiel in der Datei src/App.svelte
an.
<script> export let name; </script> <style> h1 { color: purple; } </style> <h1>{name}</h1>
Der obige Code enthält genau drei Abschnitte:
script
-Tag, bei dem es sich um einen optionalen JavaScript-Block mit den Variablen- und Funktionsdeklarationen handelt, die innerhalb der Komponente verwendet werden sollten.style
-Tag, das ein weiterer optionaler Block ist. Es ähnelt einem gewöhnlichen Tag im HTML-Stil, abgesehen von einem wichtigen Unterschied. Die in diesem Block beschriebenen Regeln gelten nur für diese Komponente. Das Anwenden eines Stils auf einp
-Element wirkt sich nicht auf alle Absätze auf der Seite aus. Das ist fantastisch, da Sie sich keine Klassennamen ausdenken müssen und nie versehentlich eine andere Regel außer Kraft setzen.Der letzte und einzige erforderliche Block ist ein Vorlagenblock – in diesem Fall ein
h1
-Tag. Es ist eine Präsentation/Ansicht Ihrer Komponente. Es ist eng an die Stil- und Skriptblöcke gebunden, da sie bestimmen, wie die Ansicht gestaltet wird und wie sie sich verhält.
Svelte ist eine Bibliothek, die versucht, Modularität in das Front-End-Spiel zu bringen. Es behält diese Modularität nicht nur bei der Trennung verschiedener Komponenten bei, sondern auch bei der Isolierung der Logik, der Ansicht und der Vorlage.
Kehren wir zum Anmeldeformular zurück, das wir erstellen, und erstellen wir eine neue Datei LoginForm.svelte
im Ordner src
mit folgendem Inhalt:
<style> form { background: #fff; padding: 50px; width: 250px; height: 400px; display: flex; flex-direction: column; justify-content: center; align-items: center; box-shadow: 0px 20px 14px 8px rgba(0, 0, 0, 0.58); } label { margin: 10px 0; align-self: flex-start; font-weight: 500; } input { border: none; border-bottom: 1px solid #ccc; margin-bottom: 20px; transition: all 300ms ease-in-out; width: 100%; } input:focus { outline: 0; border-bottom: 1px solid #666; } button { margin-top: 20px; background: black; color: white; padding: 10px 0; width: 200px; border-radius: 25px; text-transform: uppercase; font-weight: bold; cursor: pointer; transition: all 300ms ease-in-out; } button:hover { transform: translateY(-2.5px); box-shadow: 0px 1px 10px 0px rgba(0, 0, 0, 0.58); } h1 { margin: 10px 20px 30px 20px; font-size: 40px; } </style> <form> <h1></h1> <label>Email</label> <input name="email" placeholder="[email protected]" /> <label>Password</label> <input name="password" type="password" placeholder="password" /> <button type="submit">Log in </button> </form>
Es ist eine dumm gestaltete Komponente, die wir später intelligenter machen werden. Um diese Komponente auf unserer Website zu sehen, sollten wir sie innerhalb der Root-Komponente – App – rendern. Lass uns gehen und die src/App.svelte
so bearbeiten, dass sie so aussieht:
<script> import LoginForm from "./LoginForm.svelte"; </script> <style> section { height: 100vh; width: 100%; display: flex; justify-content: center; align-items: center; background: linear-gradient(to right, #cd76e2, #e358ab); } </style> <section> <LoginForm /> </section>
Wenn alles richtig gemacht wurde und die Anwendung noch läuft, erscheint unser Formular unter localhost:5000
. Lassen Sie uns unsere Svelte-Fähigkeiten verbessern, indem wir das Formular intelligenter machen.
Stateful werden
Jede Komponente in Svelte kann ihren Zustand haben. Der Zustand ist eine spezielle Variable oder eine Gruppe von speziellen Variablen, die innerhalb der Vorlage verwendet werden können. Warum sage ich „besonders“? Immer wenn eine solche Variable geändert wird, wird das Template darüber benachrichtigt und rendert den Inhalt mit dem neuesten Stand. Dadurch kann die Anwendung sehr schnell auf Benutzerinteraktionen reagieren.
Wir deklarieren E- email
und password
-Statusvariablen, in denen die Formularwerte für die entsprechenden Felder gespeichert werden. Das bedeutet, dass unsere email
und password
-Variablen immer mit den Formularwerten synchronisiert sind, sodass wir jederzeit bereit sind, diese Werte zu übermitteln, ohne befürchten zu müssen, dass es zu Abweichungen zwischen den Übermittlungswerten und den tatsächlichen Werten im Formular kommt.
<script> let email = ""; let password = ""; let isLoading = false; const handleSubmit = () => { isLoading = true; // Simulate network request setTimeout(() => { isLoading = false; // Authorize the user }, 1000); }; </script> <style> /* Style is unchanged */ </style> <form on:submit|preventDefault={handleSubmit}> <h1></h1> <label>Email</label> <input name="email" placeholder="[email protected]" bind:value={email} /> <label>Password</label> <input name="password" type="password" bind:value={password} /> {#if isLoading}Logging in...{:else}Log in {/if} </form>
Zustandsvariablen sehen aus wie gewöhnliche JavaScript-Variablen, aber um sie mit den Formularwerten zu synchronisieren (sie an die Formularfelder zu binden), ist es notwendig, die bind:value
-Direktive zu verwenden. Es gibt auch ein paar unbekannte Dinge:
on:submit|preventDefault
ist eine Abkürzung, um das Verhalten von Standardereignissen zu verhindern. Das ist bequemer, als jedes Male.preventDefault()
schreiben zu müssen.{#if isLoading}Logging in...{:else}Log in {/if}
ist ein Teil der Vorlagensyntax von Svelte. Da im Vorlagenblock kein JS vorhanden ist, gibt es eine spezielle Syntax für die Verwendung von ifs, Schleifen usw.
Lassen Sie uns schließlich die verfügbaren Optionen verwenden, indem wir den Status verwenden, um unserem Formular eine Validierung hinzuzufügen. Dies kann erreicht werden, indem eine weitere Zustandsvariable error erstellt wird, die mit errors
gefüllt wird, wenn das Formular mit ungültigen Werten gesendet wird.
<script> let email = ""; let password = ""; let isLoading = false; let errors = {}; const handleSubmit = () => { errors = {}; if (email.length === 0) { errors.email = "Field should not be empty"; } if (password.length === 0) { errors.password = "Field should not be empty"; } if (Object.keys(errors).length === 0) { isLoading = true; // Simulate network request setTimeout(() => { isLoading = false; // Authorize the user }, 1000); } }; </script> <style> // Previous styles unchanged .errors { list-style-type: none; padding: 10px; margin: 0; border: 2px solid #be6283; color: #be6283; background: rgba(190, 98, 131, 0.3); } </style> <form on:submit|preventDefault={handleSubmit}> <h1></h1> <label>Email</label> <input name="email" placeholder="[email protected]" bind:value={email} /> <label>Password</label> <input name="password" type="password" bind:value={password} /> <button type="submit"> {#if isLoading}Logging in...{:else}Log in {/if} </button> {#if Object.keys(errors).length > 0} <ul class="errors"> {#each Object.keys(errors) as field} <li>{field}: {errors[field]}</li> {/each} </ul> {/if} </form>

Das Formular ist fast fertig. Übrig bleibt nur eine Erfolgsmeldung bei erfolgreicher Authentifizierung.

Lassen Sie uns eine Zustandsvariable zum Nachverfolgen erfolgreicher Übermittlungen erstellen, die standardmäßig false
ist. Nach erfolgreichem Absenden eines Formulars sollte der Wert dieser Variable auf true
gesetzt werden.
let isSuccess = false;
Die Funktion, die die Formularübermittlung handhabt, sollte ebenfalls geändert werden, um der Logik des Umschaltens von isSuccess
nach einer erfolgreichen Operation zu folgen.
const handleSubmit = () => { errors = {}; if (email.length === 0) { errors.email = "Field should not be empty"; } if (password.length === 0) { errors.password = "Field should not be empty"; } if (Object.keys(errors).length === 0) { isLoading = true; // Simulate network request setTimeout(() => { isLoading = false; isSuccess = true; // Authorize the user }, 1000); } };
Durch diese Änderung wechselt das Formular in den Erfolgsstatus, sobald die Übermittlung abgeschlossen ist.
Aber wenn Sie Ihren Entwicklungsserver überprüfen, werden Sie keine Änderungen im Verhalten des Formulars feststellen. Wir haben den Code geändert, aber die Vorlage noch nicht berührt. Wir müssen der Vorlage Anweisungen hinzufügen, um eine Erfolgsmeldung anzuzeigen, wenn sich ein Benutzer erfolgreich angemeldet hat. Die Vorlagensyntax von Svelte ermöglicht uns eine einfache Implementierung:
<form on:submit|preventDefault={handleSubmit}> {#if isSuccess} <div class="success"> <br /> You've been successfully logged in. </div> {:else} <h1></h1> <label>Email</label> <input name="email" placeholder="[email protected]" bind:value={email} /> <label>Password</label> <input name="password" type="password" bind:value={password} /> <button type="submit"> {#if isLoading}Logging in...{:else}Log in {/if} </button> {#if Object.keys(errors).length > 0} <ul class="errors"> {#each Object.keys(errors) as field} <li>{field}: {errors[field]}</li> {/each} </ul> {/if} {/if} </form>
Zusammenfassung mit Eigenschaften
Wir haben alles über den Zustand der internen Komponente aussortiert. Jetzt ist es an der Zeit, die externen Abhängigkeiten, die Eigenschaften oder „Props“ genannt werden, durchzugehen. Requisiten sind Eingaben oder Argumente, die an die Komponente übergeben werden, um der Komponente zu beschreiben, was erscheinen soll oder wie sich die Komponente verhalten soll.
Die Deklaration einer Eigenschaft sieht bis auf das Schlüsselwort export
ähnlich aus wie der Zustand.
<script> export let answer; </script> <p>The answer is {answer}</p>
<script> import Nested from './Nested.svelte'; </script> <Nested answer={42}/>
Es geht um die Eigenschaften. Ansagen und passen - alles, was Sie wissen müssen, um Requisiten zu verwenden.
Aber wie wirken sich diese Eigenschaften auf die Anmeldeformularkomponente aus? Props können unser Anmeldeformular generischer gestalten, indem sie die Übermittlungsfunktion in eine Eigenschaft extrahieren. Dadurch können Sie diese Komponente mit jeder Übermittlungsaktion verwenden, die Sie benötigen (Anfrage an einen Testserver, Anfrage an einen tatsächlichen Server usw.). Diese Stütze wird „Senden“ submit
und ist eine Funktion, die ein aufgelöstes Versprechen zurückgibt, wenn die Übermittlungsaktion erfolgreich war, und ein abgelehntes Versprechen, wenn ein Fehler auftritt. Lassen Sie uns die Requisite anhand des oben angegebenen Beispiels deklarieren:
export let submit;
Der Submission-Handler im Anmeldeformular sollte ebenfalls bearbeitet werden, um die neue submit
-Eigenschaft zu verwenden.
const handleSubmit = () => { errors = {}; if (email.length === 0) { errors.email = "Field should not be empty"; } if (password.length === 0) { errors.password = "Field should not be empty"; } if (Object.keys(errors).length === 0) { isLoading = true; submit({ email, password }) .then(() => { isSuccess = true; isLoading = false; }) .catch(err => { errors.server = err; isLoading = false; }); } };
Die Komponente scheint fertig zu sein. Wenn Sie jedoch zum Formular zurückkehren und versuchen, es abzusenden, werden Sie feststellen, dass sich der Zustand der Schaltfläche seit dem Laden nicht geändert hat. Außerdem gibt es eine Ausnahme in der Konsole: Uncaught TypeError: submit is not a function
. Natürlich haben wir die Requisite deklariert, aber vergessen, sie zu übergeben. Lassen Sie uns eine Funktion in der App-Komponente deklarieren und an das Anmeldeformular übergeben.
const submit = ({ email, password }) => new Promise((resolve, reject) => setTimeout(resolve, 1000));
<section> <LoginForm submit={submit} /> </section>
Jetzt funktioniert das Formular wie vorgesehen. Es kann sowohl Fehler anzeigen als auch den Benutzer informieren, wenn die Anmeldung erfolgreich war.

Kontextfreigabe
Es scheint, dass alles Notwendige zum Erstellen einer Anwendung aufgelistet ist. Mit den Eigenschaften und dem inneren Zustand sind wir startklar. Das stimmt aber nur teilweise. Diese beiden allgemeinen Punkte ermöglichen es, hochkomplexe SPAs zu entwerfen. Wenn Sie jedoch versuchen, Daten zwischen vielen verschiedenen Komponenten auszutauschen, werden Sie es sehr schwierig finden.
Das einfachste Beispiel ist eine global zugängliche user
. Viele Komponenten sollten ihr Verhalten in Bezug auf den Benutzer ändern, abhängig von der Rolle, dem Alter, dem Status usw. des Benutzers. Es ist jedoch nicht DRY, uns zu wiederholen, indem wir den Benutzer mithilfe von Requisiten an jede Komponente in der App weiterleiten.
Svelte hat dafür eine Lösung: die Kontext-API.
Die Kontext-API bietet einen Mechanismus, mit dem Komponenten miteinander „sprechen“ können, ohne Daten und Funktionen als Requisiten weiterzugeben oder viele Ereignisse zu senden. Es ist eine erweiterte Funktion, aber eine nützliche.
Lassen Sie uns den Benutzerkontext zu dem von uns entworfenen Anmeldeformular hinzufügen. Erstellen Sie eine Datei userContext.js
im Ordner src
mit folgendem Inhalt:
export const key = "userContext"; export const initialValue = null;
key
ist eine eindeutige Kennung für den Kontext, da eine Anwendung eine unbegrenzte Anzahl verschiedener Kontexte haben kann, die zugänglich bleiben müssen. initialValue
ist nur ein Standardwert für den Kontext, bevor er festgelegt wird.
Der nächste Schritt besteht darin, den Kontext zu unserer Anwendung hinzuzufügen. Navigieren Sie zur Datei App.svelte
und fügen Sie zwei Importanweisungen hinzu:
import { onMount, setContext } from "svelte"; import { key as userContextKey, initialValue as userContextInitialValue } from "./userContext";
Wenn Sie sich den obigen Code ansehen, fragen Sie sich vielleicht, was wir aus dem svelte
-Paket importieren. onMount
ist eine Hilfsfunktion, die eine Callback-Funktion als Argument benötigt. Dieser Callback wird ausgeführt, wenn die aktuelle Komponente gemountet wird (gleich zu Beginn des Ladens der Komponente). setContext
ist eine Setter-Funktion für einen Kontext. Es erfordert den Schlüssel zum Kontext und einen neuen Wert als Argumente.
Verwenden wir die Funktion onMount
, um den Standardwert für den Kontext festzulegen:
onMount(() => { setContext(userContextKey, userContextInitialValue); });
Und ändern Sie die submit
-Funktion, um den Benutzerkontext festzulegen:
const submit = ({ email, password }) => new Promise((resolve, reject) => { setTimeout(() => { setContext(userContextKey, { name: "Foo", lastName: "Bar", email: "[email protected]" }); resolve(); }, 1000); });
Das ist es. Eine erfolgreiche Übermittlung ändert den Benutzerkontext in ein gefälschtes Benutzerobjekt, auf das durch einen Kontext-Getter getContext
zugegriffen werden kann:
<script> import { getContext } from 'svelte'; import { key as userContextKey } from "./userContext"; const user = getContext(key); </script>
Zusammenfassung
Svelte ist ein leistungsstarkes Tool mit hoher Leistung und einer flexiblen API. Neben den in diesem Beitrag behandelten Grundlagen verfügt Svelte über die folgenden sofort einsatzbereiten Funktionen:
- Reaktive Erklärungen und Aussagen
- Warten Sie auf Vorlagenblöcke
- Dimensionsbindung
- Ein globales Geschäft wie Redux
- Animations- und Übergangshelfer
- Ein Debugging-Helfer
Zusammenfassend ist Svelte eine großartige Bibliothek, die alle Anforderungen für den Bau von SPAs und mehr erfüllt. Es kann mit den größten Spielern auf dem Markt konkurrieren und sogar gewinnen. Was es jetzt jedoch gebrauchen könnte, ist Unterstützung in der Community der Frontend-Entwickler.
Hinweis: Der gesamte Code in diesem Artikel befindet sich im GitHub-Repository teimurjan/svelte-login-form
. Die Demo für das Anmeldeformular finden Sie hier.