Mai ușor și mai rapid - Un ghid pentru cadrul Svelte
Publicat: 2022-03-11Aplicațiile web devin din ce în ce mai populare pe zi ce trece. Sunt o lume în creștere pe care oamenii o aleg pentru simplitatea, viteza și disponibilitatea pe mai multe platforme. Aplicațiile cu o singură pagină (SPA) au avut un rol important în acest proces. Framework-uri precum Angular, Vue.js și React ajută dezvoltatorii să ofere cea mai bună experiență de utilizare într-o perioadă scurtă, lăsând codul acceptabil și extensibil. Aceste instrumente au rămas mult timp cele mai populare în domeniu, cu multe avantaje față de pachetele nou create. S-a simțit ca un oligopol în lumea SPA. Cu toate acestea, un grup de dezvoltatori de perspectivă care vizează această piață ar putea intra cu un concurent serios – Svelte.
Svelte este o nouă abordare a construirii interfețelor utilizator. Să ne aprofundăm și să explorăm ceea ce îl face atât de proaspăt, creând un formular comun de conectare.
Arhitectură
Svelte este proiectat pentru a fi mai rapid decât orice altă bibliotecă. Se ajunge prin schimbarea pasului de încărcare a unui cadru pentru construirea unui DOM virtual. În loc să folosească un instrument în timpul procesului de rulare, acesta este compilat în vanilla JS în etapa de construire, astfel încât aplicația nu necesită dependențe pentru a porni.
Svelt | Alte biblioteci SPA (React, Vue.js, Angular etc.) |
---|---|
1. Deschideți un site web | 1. Deschideți un site web |
Tabelul de mai sus descrie de ce Svelte este un câștigător absolut în performanța startup-urilor. Acest lucru nu este obținut prin niciun fel de optimizare, ci prin utilizarea compilatorului JavaScript de browser disponibil în loc de un compilator lateral.
Instalare
Instalarea sveltă este incredibil de ușoară, făcându-i folosirea foarte plăcută. Primul pas este să descărcați șablonul proiectului:
npx degit sveltejs/template svelte-login-form
Completarea comenzii de mai sus înseamnă că avem un șablon de proiect Svelte. Este gol pentru moment și pachetele NPM necesare nu sunt încă instalate. Să reparăm asta.
cd svelte-login-form npm install
Acum aplicația este gata să pornească folosind următoarea comandă:
npm run dev
Structura
Orice componentă Svelte poate conține următoarele secțiuni:
- Scenariul
- Stil
- Șablon
Să ne uităm la exemplul din fișierul src/App.svelte
.
<script> export let name; </script> <style> h1 { color: purple; } </style> <h1>{name}</h1>
Codul de mai sus conține exact trei secțiuni:
etichetă de
script
, care este un bloc JavaScript opțional cu declarațiile de variabile și funcții care ar trebui utilizate în interiorul componentei.etichetă de
style
, care este un alt bloc opțional. Este mult ca o etichetă obișnuită în stil HTML, cu excepția unei diferențe importante. Regulile descrise în interiorul acestui bloc sunt acoperite doar de această componentă. Aplicarea unui stil unui elementp
nu va afecta toate paragrafele din pagină. Este fantastic, deoarece nu trebuie să veniți cu nume de clasă și nu veți trece niciodată din greșeală pe altă regulă.Ultimul și singurul bloc necesar este un bloc șablon - în acest caz, o etichetă
h1
. Este o prezentare/vizualizare a componentei dvs. Este strâns legat de blocurile de stil și script, deoarece acestea determină modul în care va fi stilată vizualizarea și cum se va comporta.
Svelte este o bibliotecă care încearcă să aducă modularitate în jocul front-end. Păstrează această modularitate nu numai în separarea diferitelor componente, ci și în izolarea logicii, a vizualizării și a șablonului.
Revenind la formularul de conectare pe care îl construim, să creăm un nou fișier LoginForm.svelte
în folderul src
cu următorul conținut:
<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>
Este o componentă cu stil prost pe care o vom face mai inteligentă mai târziu. Pentru a vedea această componentă pe site-ul nostru ar trebui să o redăm în interiorul componentei rădăcină - App. Hai să edităm src/App.svelte
, astfel încât să arate așa:
<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>
Dacă totul a fost făcut corect și aplicația încă rulează, formularul nostru va apărea la localhost:5000
. Să ne creștem abilitățile Svelte făcând forma mai inteligentă.
Devenind Stateful
Orice componentă din Svelte poate avea starea ei. Starea este o variabilă specială sau un grup de variabile speciale care pot fi utilizate în interiorul șablonului. De ce spun „special”? Ori de câte ori o astfel de variabilă este schimbată, șablonul este notificat despre aceasta și redă conținutul cu cea mai nouă stare. Acest lucru permite aplicației să reacționeze foarte rapid la interacțiunile utilizatorului.
Vom declara variabilele de stare a e- email
și a password
în care vor fi stocate valorile formularului pentru câmpurile corespunzătoare. Înseamnă că variabilele noastre de e- email
și password
vor fi întotdeauna sincronizate cu valorile formularului, așa că vom fi gata să trimitem aceste valori în orice moment, fără teama de a avea vreo diferență între valorile trimise și valorile reale din formular.
<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>
Variabilele de stat arată ca variabile JavaScript comune, dar pentru a le face sincronizate cu valorile formularului (legați-le la câmpurile formularului), este necesar să utilizați directiva bind:value
. Există, de asemenea, câteva lucruri necunoscute:
on:submit|preventDefault
este prescurtarea pentru prevenirea comportamentului evenimentelor implicite. Este mai confortabil în acest fel decât a trebui să scrieție.preventDefault()
de fiecare dată.{#if isLoading}Logging in...{:else}Log in {/if}
este o parte din sintaxa șablonului Svelte. Deoarece nu există JS în blocul șablon, există o sintaxă specială pentru utilizarea ifs, bucle etc.
În cele din urmă, să folosim opțiunile disponibile utilizând starea pentru a adăuga validarea formularului nostru. Se poate realiza prin crearea unei alte variabile de stare errors
, care vor fi umplute cu erori atunci când formularul este trimis cu valori nevalide.
<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>

Formularul este aproape complet. Singurul lucru care rămâne este un mesaj de succes la autentificarea cu succes.

Să creăm o variabilă de stare pentru urmărirea trimiterilor de succes, care este false
în mod implicit. După trimiterea cu succes a unui formular, valoarea acestei variabile trebuie setată la true
.
let isSuccess = false;
Funcția care gestionează trimiterea formularului ar trebui, de asemenea, modificată pentru a urma logica isSuccess
după o operație de succes.
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); } };
Această modificare face ca formularul să intre în starea de succes imediat ce trimiterea este completă.
Dar dacă vă verificați serverul de dezvoltare, nu veți găsi nicio modificare în comportamentul formularului. Am schimbat codul, dar nu am atins încă șablonul. Trebuie să adăugăm instrucțiuni la șablon pentru a afișa un mesaj de succes atunci când un utilizator s-a conectat cu succes. Sintaxa șablonului Svelte ne permite să implementăm acest lucru cu ușurință:
<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>
Rezumat cu proprietăți
Am rezolvat totul despre starea componentei interne. Acum este timpul să trecem prin dependențele externe numite proprietăți sau „recuzită”. Recuzitele sunt intrări sau argumente transmise în componentă pentru a descrie componentei ce ar trebui să apară sau cum ar trebui să se comporte componenta.
Declarația unei proprietăți arată similar cu starea, cu excepția cuvântului cheie export
.
<script> export let answer; </script> <p>The answer is {answer}</p>
<script> import Nested from './Nested.svelte'; </script> <Nested answer={42}/>
Totul ține de proprietăți. Declarați și treceți - tot ce trebuie să știți pentru a folosi recuzită.
Dar cum se aplică aceste proprietăți componentei formularului de conectare? Props poate face formularul nostru de conectare mai generic prin extragerea funcției de trimitere într-o proprietate. Vă va permite să utilizați această componentă cu orice acțiune de trimitere de care aveți nevoie (solicitare către un server de testare, solicitare către un server real etc.). Acest suport va fi numit submit
și va fi o funcție care returnează o promisiune rezolvată dacă acțiunea de trimitere a reușit și o promisiune respinsă dacă există o eroare. Să declarăm prop prin exemplul dat mai sus:
export let submit;
Managerul de trimitere din formularul de conectare ar trebui, de asemenea, editat pentru a utiliza noua proprietate de submit
.
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; }); } };
Componenta pare a fi gata. Cu toate acestea, dacă reveniți la formular și încercați să-l trimiteți, veți observa că starea butonului nu s-a schimbat de la încărcare. De asemenea, există o excepție în consolă: Uncaught TypeError: submit is not a function
. Desigur, am declarat recuzita, dar am uitat să o trecem. Să declarăm o funcție în componenta aplicației și să o transmitem în formularul de conectare.
const submit = ({ email, password }) => new Promise((resolve, reject) => setTimeout(resolve, 1000));
<section> <LoginForm submit={submit} /> </section>
Acum formularul funcționează conform intenției. Poate afișa erori și poate informa utilizatorul dacă autentificarea a avut succes.

Partajarea contextului
Se pare că este listat tot ceea ce este necesar pentru a construi o aplicație. Cu proprietățile și starea interioară, suntem gata să mergem. Asta e doar parțial adevărat, totuși. Aceste două puncte generale fac posibilă proiectarea SPA-urilor de mare complexitate. Cu toate acestea, dacă încercați să partajați date între mai multe componente diferite, vă va fi foarte dificil.
Cel mai simplu exemplu este acela de a avea o variabilă user
accesibilă la nivel global. O mulțime de componente ar trebui să-și schimbe comportamentul legat de utilizator, în funcție de rolul utilizatorului, vârsta, statutul etc. Cu toate acestea, nu este USAT să ne repetăm trecând utilizatorul la fiecare componentă din aplicație folosind recuzită.
Svelte are o soluție pentru asta: API-ul context.
API-ul context oferă un mecanism pentru ca componentele să „vorbească” între ele fără a transmite date și funcționează ca elemente de recuzită sau trimițând o mulțime de evenimente. Este o caracteristică avansată, dar utilă.
Să adăugăm contextul utilizatorului în formularul de conectare pe care îl proiectăm. Creați un fișier userContext.js
în folderul src
cu următorul conținut:
export const key = "userContext"; export const initialValue = null;
key
este un identificator unic pentru context, deoarece o aplicație poate avea un număr nelimitat de contexte diferite care trebuie să rămână accesibile. initialValue
este doar o valoare implicită pentru context înainte de a fi setat.
Următorul pas este să adăugați contextul aplicației noastre. Navigați la fișierul App.svelte
și adăugați 2 declarații de import:
import { onMount, setContext } from "svelte"; import { key as userContextKey, initialValue as userContextInitialValue } from "./userContext";
Privind codul de mai sus, s-ar putea să vă întrebați ce importăm din pachetul svelte
. onMount
este o funcție de ajutor care necesită o funcție de apel invers ca argument. Acest apel invers va fi executat când componenta curentă este montată (la începutul încărcării componentei). setContext
este o funcție setter pentru un context. Ea necesită cheia contextului și o nouă valoare ca argumente.
Să folosim funcția onMount
pentru a seta valoarea implicită pentru context:
onMount(() => { setContext(userContextKey, userContextInitialValue); });
Și modificați funcția de submit
pentru a seta contextul utilizatorului:
const submit = ({ email, password }) => new Promise((resolve, reject) => { setTimeout(() => { setContext(userContextKey, { name: "Foo", lastName: "Bar", email: "[email protected]" }); resolve(); }, 1000); });
Asta e. O trimitere reușită va schimba contextul utilizatorului într-un obiect utilizator fals care poate fi accesat de un getContext
de obținere a contextului:
<script> import { getContext } from 'svelte'; import { key as userContextKey } from "./userContext"; const user = getContext(key); </script>
rezumat
Svelte este un instrument puternic capabil de înaltă performanță și cu un API flexibil. Pe lângă elementele de bază abordate în această postare, Svelte are următoarele caracteristici:
- Declarații și declarații reactive
- Așteptați blocurile de șablon
- Legarea dimensiunilor
- Un magazin global precum Redux
- Ajutor de animație și tranziție
- Un ajutor de depanare
Pentru a rezuma, Svelte este o bibliotecă grozavă care îndeplinește toate nevoile pentru construirea de SPA-uri și multe altele. Poate concura cu cei mai mari jucători de pe piață și chiar poate câștiga. Totuși, ceea ce ar putea folosi chiar acum este suport în comunitatea dezvoltatorilor front-end.
Notă: Tot codul din acest articol poate fi găsit în depozitul GitHub teimurjan/svelte-login-form
. Demo-ul pentru formularul de autentificare este disponibil aici.