SvelteKit este cel mai recent dintre ceea ce aș numi cadre de aplicații de nouă generație. Desigur, oferă o aplicație pentru dvs., cu rutarea bazată pe fișiere, implementarea și redarea pe partea serverului pe care Next le-a făcut pentru totdeauna. Dar SvelteKit acceptă, de asemenea, layout-uri imbricate, mutații de server care sincronizează datele de pe pagina ta și alte detalii în care vom intra.
Această postare este menită să fie o introducere la nivel înalt pentru a crea un pic de entuziasm pentru oricine care nu a folosit niciodată SvelteKit. Va fi un tur relaxat. Dacă vă place ceea ce vedeți, documentele complete sunt aici.
Într-un fel, aceasta este o postare dificilă de scris. SvelteKit este un cadru de aplicare. Există pentru a vă ajuta să construiți... ei bine, aplicații. Asta face dificilă demonstrația. Nu este fezabil să construiți o aplicație întreagă într-o postare de blog. Deci, în schimb, ne vom folosi puțin imaginația. Vom construi scheletul unei aplicații, vom avea niște substituenți de UI goale și date statice codificate. Scopul nu este de a construi o aplicație reală, ci de a vă arăta cum funcționează piesele mobile ale SvelteKit, astfel încât să puteți construi o aplicație proprie.
În acest scop, vom construi aplicația To-Do, încercată și adevărată, ca exemplu. Dar nu vă faceți griji, va fi mult, mult mai mult despre a vedea cum funcționează SvelteKit decât să creați încă o altă aplicație To-Do.
Codul pentru tot în această postare este disponibil pe GitHub. Acest proiect este, de asemenea dislocat pe Vercel pentru o demonstrație live.
Crearea proiectului dvs.
Crearea unui nou proiect SvelteKit este destul de simplă. Alerga npm create your-app-name
în terminal și răspundeți la întrebări. Asigurați-vă că alegeți „Skeleton Project”, dar, altfel, faceți orice selecție doriți pentru TypeScript, ESLint etc.
Odată ce proiectul este creat, rulați npm i
și npm run dev
iar un server de dezvoltare ar trebui să înceapă să ruleze. A da foc localhost:5173
în browser și veți obține pagina de substituent pentru aplicația Skeleton.
Rutare de bază
Observați routes
dosarul de sub src
. Acesta conține codul pentru toate rutele noastre. Există deja un +page.svelte
fișier acolo cu conținut pentru rădăcină /
traseu. Indiferent unde vă aflați în ierarhia fișierelor, pagina reală pentru acea cale are întotdeauna numele +page.svelte
. Având în vedere asta, să creăm pagini pentru /list
, /details
, /admin/user-settings
și admin/paid-status
și adăugați, de asemenea, niște substituenți de text pentru fiecare pagină.
Aspectul fișierului dvs. ar trebui să arate cam așa:
Ar trebui să puteți naviga prin schimbarea căilor URL din bara de adrese a browserului.
aspecte
Vom dori linkuri de navigare în aplicația noastră, dar cu siguranță nu vrem să copiem marcajul pentru ele pe fiecare pagină pe care o creăm. Deci, să creăm un +layout.svelte
fișier în rădăcina noastră routes
folder, pe care SvelteKit îl va trata ca un șablon global pentru toate paginile. Să adăugăm ceva conținut la el:
<nav> <ul> <li> <a href="/ro/">Home</a> </li> <li> <a href="/ro/list">To-Do list</a> </li> <li> <a href="/ro/admin/paid-status">Account status</a> </li> <li> <a href="/ro/admin/user-settings">User settings</a> </li> </ul>
</nav> <slot /> <style> nav { background-color: beige; } nav ul { display: flex; } li { list-style: none; margin: 15px; } a { text-decoration: none; color: black; }
</style>
O navigare rudimentară cu câteva stiluri de bază. De o importanță deosebită este <slot />
etichetă. Aceasta este nu slotul pe care îl utilizați cu componente web și shadow DOM, ci mai degrabă o caracteristică Svelte care indică unde să punem conținutul nostru. Când o pagină este redată, conținutul paginii va aluneca în locul unde este slotul.
Și acum avem puțină navigare! Nu vom câștiga niciun concurs de design, dar nu încercăm.
Aspecte imbricate
Ce se întâmplă dacă am dori ca toate paginile noastre de administrare să moștenească aspectul normal pe care tocmai l-am construit, dar să împărtășească și unele lucruri comune tuturor paginilor de administrare (dar numai paginile de administrare)? Nicio problemă, adăugăm alta +layout.svelte
fișier în rădăcina noastră admin
director, care va fi moștenit de tot ce se află sub el. Să facem asta și să adăugăm acest conținut:
<div>This is an admin page</div> <slot /> <style> div { padding: 15px; margin: 10px 0; background-color: red; color: white; }
</style>
Adăugăm un banner roșu care indică că aceasta este o pagină de administrare și apoi, ca înainte, a <slot />
indicând unde vrem să ajungă conținutul paginii noastre.
Aspectul nostru rădăcină de înainte de randări. În interiorul aspectului rădăcină se află a <slot />
etichetă. Conținutul aspectului imbricat intră în aspectul rădăcină <slot />
. Și, în sfârșit, aspectul imbricat își definește propriul <slot />
, în care se redă conținutul paginii.
Dacă navigați la paginile de administrare, ar trebui să vedeți noul banner roșu:
Definirea datelor noastre
OK, să redăm niște date reale - sau cel puțin, să vedem cum putem reda niște date reale. Există o sută de moduri de a crea și de a vă conecta la o bază de date. Totuși, această postare este despre SvelteKit, nu despre gestionarea DynamoDB, așa că vom „încărca” niște date statice. Dar, vom folosi aceleași mașini pentru a-l citi și actualiza pe care le-ați folosi pentru date reale. Pentru o aplicație web reală, schimbați funcțiile care returnează date statice cu funcții de conectare și interogare la orice bază de date pe care se întâmplă să o utilizați.
Haideți să creăm un modul foarte simplu lib/data/todoData.ts
care returnează unele date statice împreună cu întârzieri artificiale pentru a simula interogări reale. Vei vedea asta lib
folder importat în altă parte prin $lib
. Aceasta este o caracteristică SvelteKit pentru acel folder anume și puteți chiar adăugați propriile aliasuri.
let todos = [ { id: 1, title: "Write SvelteKit intro blog post", assigned: "Adam", tags: [1] }, { id: 2, title: "Write SvelteKit advanced data loading blog post", assigned: "Adam", tags: [1] }, { id: 3, title: "Prepare RenderATL talk", assigned: "Adam", tags: [2] }, { id: 4, title: "Fix all SvelteKit bugs", assigned: "Rich", tags: [3] }, { id: 5, title: "Edit Adam's blog posts", assigned: "Geoff", tags: [4] },
]; let tags = [ { id: 1, name: "SvelteKit Content", color: "ded" }, { id: 2, name: "Conferences", color: "purple" }, { id: 3, name: "SvelteKit Development", color: "pink" }, { id: 4, name: "CSS-Tricks Admin", color: "blue" },
]; export const wait = async amount => new Promise(res => setTimeout(res, amount ?? 100)); export async function getTodos() { await wait(); return todos;
} export async function getTags() { await wait(); return tags.reduce((lookup, tag) => { lookup[tag.id] = tag; return lookup; }, {});
} export async function getTodo(id) { return todos.find(t => t.id == id);
}
O funcție pentru a returna o matrice plată a elementelor noastre de făcut, o căutare a etichetelor noastre și o funcție pentru a prelua o singură activitate (o vom folosi pe ultima în pagina noastră de detalii).
Se încarcă datele noastre
Cum introducem aceste date în paginile noastre Svelte? Există mai multe moduri, dar, deocamdată, să creăm un +page.server.js
dosarul nostru list
folder și puneți acest conținut în el:
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); const tags = getTags(); return { todos, tags, };
}
Am definit un load()
funcție care extrage datele necesare pentru pagină. Observați că suntem nu await
-ing apelurile noastre getTodos
și getTags
funcții asincrone. Procedând astfel, s-ar crea o cascadă de încărcare a datelor în timp ce așteptăm ca elementele noastre de făcut să vină înainte de a ne încărca etichetele. În schimb, returnăm promisiunile brute de la load
, iar SvelteKit face munca necesară await
Le.
Deci, cum accesăm aceste date din componenta paginii noastre? SvelteKit oferă o data
prop pentru componenta noastră cu date despre ea. Vom accesa articolele noastre de făcut și etichetele din acesta folosind a atribuire reactivă.
Componenta noastră de pagină Listă arată acum astfel.
<script> export let data; $: ({ todo, tags } = data);
</script> <table cellspacing="10" cellpadding="10"> <thead> <tr> <th>Task</th> <th>Tags</th> <th>Assigned</th> </tr> </thead> <tbody> {#each todos as t} <tr> <td>{t.title}</td> <td>{t.tags.map((id) => tags[id].name).join(', ')}</td> <td>{t.assigned}</td> </tr> {/each} </tbody>
</table> <style> th { text-align: left; }
</style>
Și acest lucru ar trebui să facă obiectele noastre de făcut!
Grupuri de layout
Înainte de a trece la pagina Detalii și de a modifica datele, să aruncăm o privire la o caracteristică SvelteKit foarte bună: grupuri de layout. Am văzut deja aspecte imbricate pentru toate paginile de administrare, dar ce se întâmplă dacă am dori să partajăm un aspect între pagini arbitrare la același nivel al sistemului nostru de fișiere? În special, ce se întâmplă dacă am dori să partajăm un aspect doar între pagina noastră Listă și pagina noastră Detalii? Avem deja un aspect global la acel nivel. În schimb, putem crea un director nou, dar cu un nume care este în paranteză, astfel:
Acum avem un grup de aspect care acoperă paginile noastre Listă și Detalii. L-am numit (todo-management)
dar îi poți numi cum vrei. Pentru a fi clar, acest nume va fi nu afectează adresele URL ale paginilor din interiorul grupului de aspect. URL-urile vor rămâne aceleași; grupurile de aspect vă permit să adăugați machete partajate la pagini fără ca toate să cuprindă întregul director în care se află routes
.
We ar putea adauga o +layout.svelte
dosar si niste prosti <div>
banner care spune: „Hei, reușim să facem”. Dar haideți să facem ceva mai interesant. Aspectele pot defini load()
funcții pentru a furniza date pentru toate rutele de sub ele. Să folosim această funcționalitate pentru a încărca etichetele noastre - deoarece vom folosi etichetele noastre în nostru details
pagina — în plus față de list
pagina pe care o avem deja.
În realitate, forțarea unui grup de layout doar pentru a furniza o singură bucată de date aproape sigur nu merită; este mai bine să duplicați acele date în load()
funcţie pentru fiecare pagină. Dar pentru această postare, ne va oferi scuza de care avem nevoie pentru a vedea o nouă funcție SvelteKit!
În primul rând, să intrăm în noul nostru list
paginilor +page.server.js
fișier și eliminați etichetele din acesta.
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); return { todos, };
}
Pagina noastră Listă ar trebui să producă acum o eroare, deoarece nu există tags
obiect. Să remediem acest lucru adăugând un +layout.server.js
fișier în grupul nostru de aspect, apoi definiți a load()
funcția care ne încarcă etichetele.
import { getTags } from "$lib/data/todoData"; export function load() { const tags = getTags(); return { tags, };
}
Și, exact așa, pagina noastră Listă se redă din nou!
Încărcăm date din mai multe locații
Să punem un punct bun asupra a ceea ce se întâmplă aici:
- Am definit o
load()
funcție pentru grupul nostru de layout, pe care l-am introdus+layout.server.js
. - Aceasta oferă date pentru toate dintre paginile pe care le servește aspectul — ceea ce înseamnă, în acest caz, paginile noastre Listă și Detalii.
- Pagina noastră Listă definește, de asemenea, a
load()
funcția care merge în ea+page.server.js
fișier. - SvelteKit face munca groaznică de a prelua rezultatele acestor surse de date, de a le îmbina și de a le face disponibile în
data
.
Pagina noastră de detalii
Vom folosi pagina noastră Detalii pentru a edita un articol de făcut. În primul rând, să adăugăm o coloană la tabelul din pagina noastră Listă care face link la pagina Detalii cu ID-ul articolului de făcut în șirul de interogare.
<td><a href="/ro/details?id={t.id}">Edit</a></td>
Acum să construim pagina noastră de detalii. Mai întâi, vom adăuga un încărcător pentru a prelua elementul de făcut pe care îl edităm. Creeaza o +page.server.js
in /details
, cu acest continut:
import { getTodo, updateTodo, wait } from "$lib/data/todoData"; export function load({ url }) { const id = url.searchParams.get("id"); console.log(id); const todo = getTodo(id); return { todo, };
}
Încărcătorul nostru vine cu un url
proprietate din care putem extrage valorile șirului de interogare. Acest lucru facilitează căutarea elementului de făcut pe care îl edităm. Să redăm această activitate de făcut, împreună cu funcționalitatea de editare.
SvelteKit are capabilități minunate de mutare încorporate, atâta timp cât utilizați formulare. Vă amintiți formularele? Iată pagina noastră de detalii. Am eliminat stilurile pentru concizie.
<script> import { enhance } from "$app/forms"; export let data; $: ({ todo, tags } = data); $: currentTags = todo.tags.map(id => tags[id]);
</script> <form use:enhance method="post" action="?/editTodo"> <input name="id" type="hidden" value="{todo.id}" /> <input name="title" value="{todo.title}" /> <div> {#each currentTags as tag} <span style="{`color:" ${tag.color};`}>{tag.name}</span> {/each} </div> <button>Save</button>
</form>
Luăm etichetele ca înainte din încărcătorul grupului nostru de aspect și elementul de făcut din încărcătorul paginii noastre. Prindem realitatea tag
obiecte din lista de ID-uri a etichetelor de făcut și apoi redarea totul. Creăm un formular cu o intrare ascunsă pentru ID și o intrare reală pentru titlu. Afișăm etichetele și apoi oferim un buton pentru a trimite formularul.
Dacă ai observat use:enhance
, care spune pur și simplu SvelteKit să folosească îmbunătățirea progresivă și Ajax pentru a trimite formularul nostru. Probabil o vei folosi întotdeauna.
Cum ne salvăm editările?
Observați action="?/editTodo"
atribut pe formular în sine? Acest lucru ne spune unde vrem să trimitem datele noastre editate. Pentru cazul nostru, dorim să ne supunem unui editTodo
"acțiune."
Să-l creăm adăugând următoarele la +page.server.js
fișierul pe care îl avem deja pentru Detalii (care în prezent are un load()
funcția, pentru a ne lua de făcut):
import { redirect } from "@sveltejs/kit"; // ... export const actions = { async editTodo({ request }) { const formData = await request.formData(); const id = formData.get("id"); const newTitle = formData.get("title"); await wait(250); updateTodo(id, newTitle); throw redirect(303, "/list"); },
};
Acțiunile de formă ne oferă a request
obiect, care oferă acces la nostru formData
, care are un get
metoda pentru diferitele noastre câmpuri de formular. Am adăugat acea intrare ascunsă pentru valoarea ID, astfel încât să o putem lua aici pentru a căuta elementul de făcut pe care îl edităm. Simulăm o întârziere, sunăm un nou updateTodo()
metoda, apoi redirecționați utilizatorul înapoi la /list
pagină. The updateTodo()
metoda doar actualizează datele noastre statice; în viața reală, ați rula un fel de actualizare în orice depozit de date pe care îl utilizați.
export async function updateTodo(id, newTitle) { const todo = todos.find(t => t.id == id); Object.assign(todo, { title: newTitle });
}
Hai să-l încercăm. Vom merge mai întâi la pagina Listă:
Acum să facem clic pe butonul Editați pentru unul dintre elementele de făcut pentru a afișa pagina de editare /details
.
Vom adăuga un nou titlu:
Acum, faceți clic pe Salvare. Asta ar trebui să ne aducă înapoi la noi /list
pagină, cu noul titlu aplicat.
Cum a apărut noul titlu așa? A fost automat. Odată ce am redirecționat către /list
pagina, SvelteKit a rulat din nou automat toate încărcătoarele noastre, așa cum ar fi făcut-o oricum. Acesta este progresul cheie pe care cadrele de aplicații de nouă generație, cum ar fi SvelteKit, Remix, și Următorul 13 oferi. În loc să vă ofere o modalitate convenabilă de a reda paginile, apoi să vă dorească mult noroc pentru a prelua orice puncte finale pe care le-ați putea actualiza datele, ele integrează mutația datelor împreună cu încărcarea datelor, permițând celor două să lucreze în tandem.
Câteva lucruri pe care s-ar putea să vă întrebați...
Această actualizare cu mutații nu pare prea impresionantă. Încărcătoarele vor rula din nou ori de câte ori navigați. Ce se întâmplă dacă nu am fi adăugat o redirecționare în acțiunea din formular, dar am fi rămas pe pagina curentă? SvelteKit ar efectua actualizarea în acțiunea de formular, ca înainte, dar ar face-o încă rulați din nou toate încărcătoarele pentru pagina curentă, inclusiv încărcătoarele din aspectul(ele) de pagină.
Putem avea mijloace mai direcționate de a ne invalida datele? De exemplu, etichetele noastre nu au fost editate, așa că în viața reală nu am dori să le interogăm din nou. Da, ceea ce v-am arătat este doar comportamentul implicit al formularelor din SvelteKit. Puteți dezactiva comportamentul implicit prin oferind un apel invers către use:enhance
. Apoi SvelteKit oferă manual funcții de invalidare.
Încărcarea datelor pentru fiecare navigație este potențial costisitoare și inutilă. Pot stoca aceste date în cache așa cum fac cu instrumente precum react-query
? Da, doar altfel. SvelteKit vă permite să setați (și apoi să respectați) anteturile de control cache pe care web le oferă deja. Și voi acoperi mecanismele de invalidare a memoriei cache într-o postare ulterioară.
Tot ceea ce am făcut în acest articol utilizează date statice și modifică valorile din memorie. Dacă trebuie să anulați totul și să o luați de la capăt, opriți și reporniți npm run dev
Procesul nodului.
La finalul
Abia am zgâriat suprafața SvelteKit, dar sperăm că ați văzut suficient pentru a vă entuziasma. Nu-mi amintesc ultima dată când am găsit dezvoltarea web atât de distractiv. Cu lucruri precum gruparea, rutarea, SSR și implementarea, toate gestionate imediat, pot să petrec mai mult timp codificând decât configurând.
Iată câteva resurse suplimentare pe care le puteți folosi ca următorii pași de învățare a SvelteKit:
- Distribuție de conținut bazat pe SEO și PR. Amplifică-te astăzi.
- Platoblockchain. Web3 Metaverse Intelligence. Cunoștințe amplificate. Accesați Aici.
- Sursa: https://css-tricks.com/getting-started-with-sveltekit/
- 1
- 10
- 100
- 11
- 7
- 9
- 98
- a
- Capabil
- Despre Noi
- despre
- acces
- Cont
- Acțiune
- acțiuni
- Adam
- adăugat
- plus
- adresa
- admin
- avansat
- afecta
- TOATE
- Permiterea
- pe langa
- deja
- mereu
- sumă
- și
- O alta
- răspunde
- oricine
- aplicaţia
- aplicație
- aplicatii
- aplicat
- în jurul
- Mulțime
- articol
- artificial
- alocate
- Automat
- în mod automat
- disponibil
- astept
- înapoi
- fundal
- steag
- bar
- de bază
- înainte
- CEL MAI BUN
- Mai bine
- între
- Pic
- Negru
- Blog
- Blog
- Albastru
- Cutie
- aduce
- browser-ul
- gandaci
- construi
- construit
- construit-in
- buton
- Cache
- apel
- apeluri
- capacități
- caz
- cu siguranță
- provocare
- schimbarea
- clar
- cod
- Codificare
- culoare
- Coloană
- cum
- Comun
- Competiţii
- component
- componente
- conferințe
- Conectați
- Conectarea
- Consoleze
- conţinut
- Convenabil
- ar putea
- Curs
- acoperire
- Covers
- crea
- a creat
- Crearea
- Curent
- În prezent
- de date
- Baza de date
- Mod implicit
- defineste
- întârziere
- întârzieri
- desfășurarea
- Amenajări
- detalii
- dev
- Dezvoltare
- FĂCUT
- Afişa
- Nu
- face
- Dont
- fiecare
- în altă parte
- suficient de
- Întreg
- întregime
- eroare
- etc
- Chiar
- Fiecare
- tot
- exemplu
- excitat
- Excitare
- există
- scump
- exporturile
- realizabil
- Caracteristică
- puțini
- Domenii
- Fișier
- Fişiere
- În cele din urmă
- capăt
- Incendiu
- First
- Repara
- plat
- următor
- pentru totdeauna
- formă
- format
- formulare
- găsit
- cadre
- din
- Complet
- distracţie
- funcţie
- funcționalitate
- funcții
- obține
- obtinerea
- Da
- Oferirea
- Caritate
- Go
- scop
- Merge
- merge
- apuca
- grup
- Grupului
- întâmpla
- Greu
- anteturile
- ajutor
- aici
- Ascuns
- ierarhie
- la nivel înalt
- deține
- In speranta
- Orizontală
- Cum
- HTML
- HTTPS
- BOLNAV
- imaginația
- import
- importanță
- impresionant
- in
- Inclusiv
- inițială
- intrare
- in schimb
- integra
- interesant
- Introducere
- IT
- articole
- în sine
- JavaScript
- Cheie
- Nume
- Ultimele
- Aspect
- învăţare
- Permite
- Nivel
- Li
- Viaţă
- ușoară
- Probabil
- Link-uri
- Listă
- trăi
- încărca
- încărcător
- încărcare
- loturile
- Lung
- Uite
- Se pare
- căutare
- noroc
- mașini
- face
- FACE
- Efectuarea
- de conducere
- manual
- Margine
- materie
- mijloace
- Memorie
- pur și simplu
- care fuzionează
- metodă
- ar putea
- minte
- Module
- mai mult
- muta
- în mişcare
- multiplu
- nume
- Numit
- nav
- Navigaţi
- Navigare
- necesar
- Nevoie
- Nou
- următor
- nod
- normală.
- număr
- obiect
- obiecte
- ONE
- comandă
- Altele
- in caz contrar
- propriu
- special
- cale
- Efectua
- alege
- bucată
- piese
- înlocuitor
- Plato
- Informații despre date Platon
- PlatoData
- Punct
- Post
- postări
- potenţial
- Pregăti
- Problemă
- proces
- produce
- progresiv
- proiect
- Promisiuni
- proprietate
- protejat
- furniza
- furnizează
- Trage
- pune
- întrebare
- Crud
- Citeste
- real
- viata reala
- Realitate
- Roșu
- redirecționa
- Fără deosebire
- rămâne
- minte
- scoate
- tencuială
- face
- solicita
- Resurse
- REZULTATE
- reveni
- revenind
- Returnează
- reveni
- Bogat
- rădăcină
- Traseul
- rute
- Alerga
- funcţionare
- acelaşi
- Economisiți
- vedere
- servește
- set
- Umbră
- Distribuie
- comun
- să
- Arăta
- simplu
- pur şi simplu
- întrucât
- singur
- Diapozitiv
- So
- unele
- ceva
- Surse
- petrece
- Începe
- început
- au stat
- paşi
- Stop
- prezenta
- Sprijină
- Suprafață
- sistem
- tabel
- TAG
- Lua
- luare
- Vorbi
- Tandem
- vizate
- spune
- șablon
- Terminal
- lucruri
- de-a lungul
- timp
- Titlu
- la
- împreună
- de asemenea
- Unelte
- Tur
- trata
- adevărat
- ÎNTORCĂ
- manuscris dactilografiat
- ui
- în
- Actualizează
- actualizări
- URL-ul
- us
- utilizare
- Utilizator
- valoare
- Valori
- diverse
- de
- Vizualizare
- aștepta
- dorit
- modalități de
- web
- componente web
- dezvoltare web
- Ce
- care
- alb
- voi
- câştiga
- fără
- minunat
- Apartamente
- fabrică
- valoare
- ar
- scrie
- Tu
- Ta
- zephyrnet