SvelteKit est le dernier de ce que j'appellerais les cadres d'application de nouvelle génération. Bien sûr, il échafaude une application pour vous, avec le routage, le déploiement et le rendu côté serveur basés sur des fichiers que Next a fait depuis toujours. Mais SvelteKit prend également en charge les mises en page imbriquées, les mutations de serveur qui synchronisent les données sur votre page et quelques autres subtilités dont nous parlerons.
Ce message est censé être une introduction de haut niveau pour, espérons-le, susciter l'enthousiasme de tous ceux qui n'ont jamais utilisé SvelteKit. Ce sera une visite détendue. Si vous aimez ce que vous voyez, le les docs complètes sont ici.
À certains égards, il s'agit d'un article difficile à écrire. SvelteKit est un cadre d'application. Il existe pour vous aider à créer… eh bien, des applications. Cela rend la démonstration difficile. Il n'est pas possible de créer une application entière dans un article de blog. Donc, à la place, nous allons utiliser un peu notre imagination. Nous allons construire le squelette d'une application, avoir des espaces réservés d'interface utilisateur vides et des données statiques codées en dur. Le but n'est pas de créer une application réelle, mais plutôt de vous montrer comment fonctionnent les pièces mobiles de SvelteKit afin que vous puissiez créer votre propre application.
À cette fin, nous allons créer l'application To-Do éprouvée à titre d'exemple. Mais ne vous inquiétez pas, il s'agira beaucoup plus de voir comment SvelteKit fonctionne que de créer une autre application To-Do.
Le code pour tout dans ce post est disponible sur GitHub. Ce projet est également déployé sur Vercel pour une démonstration en direct.
Créer votre projet
Lancer un nouveau projet SvelteKit est assez simple. Cours npm create your-app-name
dans le terminal et répondez aux questions. Assurez-vous de choisir "Skeleton Project", mais sinon faites les sélections que vous voulez pour TypeScript, ESLint, etc.
Une fois le projet créé, lancez npm i
ainsi que les npm run dev
et un serveur de développement devrait commencer à fonctionner. Allumez localhost:5173
dans le navigateur et vous obtiendrez la page d'espace réservé pour l'application squelette.
Routage de base
Notez le routes
dossier sous src
. Cela contient le code de toutes nos routes. Il y a déjà un +page.svelte
déposer là-dedans avec du contenu pour la racine /
itinéraire. Peu importe où vous vous trouvez dans la hiérarchie des fichiers, la page réelle de ce chemin porte toujours le nom +page.svelte
. Dans cet esprit, créons des pages pour /list
, /details
, /admin/user-settings
ainsi que les admin/paid-status
, et ajoutez également des espaces réservés de texte pour chaque page.
La mise en page de votre fichier devrait ressembler à ceci :
Vous devriez pouvoir naviguer en modifiant les chemins d'URL dans la barre d'adresse du navigateur.
layouts
Nous voudrons des liens de navigation dans notre application, mais nous ne voulons certainement pas copier le balisage pour eux sur chaque page que nous créons. Alors, créons un +layout.svelte
fichier à la racine de notre routes
dossier, que SvelteKit traitera comme un modèle global pour toutes les pages. Ajoutons-y du contenu :
<nav> <ul> <li> <a href="/fr/">Home</a> </li> <li> <a href="/fr/list">To-Do list</a> </li> <li> <a href="/fr/admin/paid-status">Account status</a> </li> <li> <a href="/fr/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>
Une navigation rudimentaire avec quelques styles de base. D'une importance particulière est la <slot />
étiqueter. C'est ne sauraient l'emplacement que vous utilisez avec les composants Web et le DOM fantôme, mais plutôt une fonctionnalité Svelte indiquant où placer notre contenu. Lorsqu'une page s'affiche, le contenu de la page glisse là où se trouve l'emplacement.
Et maintenant nous avons un peu de navigation ! Nous ne gagnerons aucun concours de design, mais nous n'essayons pas de le faire.
Dispositions imbriquées
Et si nous voulions que toutes nos pages d'administration héritent de la mise en page normale que nous venons de créer, mais partagent également certaines choses communes à toutes les pages d'administration (mais uniquement aux pages d'administration) ? Pas de problème, nous en ajoutons un autre +layout.svelte
fichier dans notre racine admin
répertoire, qui sera hérité par tout ce qui se trouve en dessous. Faisons cela et ajoutons ce contenu :
<div>This is an admin page</div> <slot /> <style> div { padding: 15px; margin: 10px 0; background-color: red; color: white; }
</style>
Nous ajoutons une bannière rouge indiquant qu'il s'agit d'une page d'administration, puis, comme avant, un <slot />
indiquant où nous voulons que le contenu de notre page aille.
Notre mise en page racine d'avant les rendus. À l'intérieur de la disposition racine se trouve un <slot />
étiqueter. Le contenu de la mise en page imbriquée va dans la mise en page racine <slot />
. Et enfin, la mise en page imbriquée définit sa propre <slot />
, dans lequel le contenu de la page s'affiche.
Si vous accédez aux pages d'administration, vous devriez voir la nouvelle bannière rouge :
Définir nos données
OK, rendons des données réelles - ou du moins, voyons comment nous pouvons rendre des données réelles. Il existe une centaine de façons de créer et de se connecter à une base de données. Ce message concerne cependant SvelteKit, et non la gestion de DynamoDB, nous allons donc « charger » des données statiques à la place. Mais, nous utiliserons tous les mêmes machines pour le lire et le mettre à jour que vous utiliseriez pour des données réelles. Pour une véritable application Web, remplacez les fonctions renvoyant des données statiques par des fonctions de connexion et d'interrogation de la base de données que vous utilisez.
Créons un module très simple dans lib/data/todoData.ts
qui renvoie des données statiques ainsi que des délais artificiels pour simuler des requêtes réelles. Vous verrez ceci lib
dossier importé ailleurs via $lib
. Il s'agit d'une fonctionnalité SvelteKit pour ce dossier particulier, et vous pouvez même ajoutez vos propres alias.
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);
}
Une fonction pour renvoyer un tableau plat de nos éléments à faire, une recherche de nos balises et une fonction pour récupérer une seule tâche (nous utiliserons cette dernière dans notre page Détails).
Chargement de nos données
Comment intégrons-nous ces données dans nos pages Svelte ? Il existe plusieurs façons, mais pour l'instant, créons un +page.server.js
déposer dans notre list
dossier et placez-y ce contenu :
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); const tags = getTags(); return { todos, tags, };
}
Nous avons défini un load()
fonction qui récupère les données nécessaires à la page. Remarquez que nous sommes ne sauraient await
-ing appels à notre getTodos
ainsi que les getTags
fonctions asynchrones. Cela créerait une cascade de chargement de données pendant que nous attendons que nos éléments à faire arrivent avant de charger nos balises. Au lieu de cela, nous retournons les promesses brutes de load
, et SvelteKit fait le travail nécessaire pour await
Eux.
Alors, comment accédons-nous à ces données depuis notre composant de page ? SvelteKit fournit un data
prop pour notre composant avec des données dessus. Nous accéderons à nos tâches et balises à partir de celui-ci à l'aide d'un affectation réactive.
Notre composant de page Liste ressemble maintenant à ceci.
<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>
Et cela devrait rendre nos choses à faire !
Groupes de mise en page
Avant de passer à la page Détails et de muter les données, jetons un coup d'œil à une fonctionnalité SvelteKit vraiment intéressante : groupes de mise en page. Nous avons déjà vu des mises en page imbriquées pour toutes les pages d'administration, mais que se passerait-il si nous voulions partager une mise en page entre des pages arbitraires au même niveau de notre système de fichiers ? En particulier, que se passerait-il si nous voulions partager une mise en page uniquement entre notre page Liste et notre page Détails ? Nous avons déjà une disposition globale à ce niveau. Au lieu de cela, nous pouvons créer un nouveau répertoire, mais avec un nom entre parenthèses, comme ceci :
Nous avons maintenant un groupe de mise en page qui couvre nos pages Liste et Détails. je l'ai nommé (todo-management)
mais vous pouvez lui donner le nom que vous voulez. Pour être clair, ce nom sera ne sauraient affecter les URL des pages à l'intérieur du groupe de mise en page. Les URL resteront les mêmes ; les groupes de mise en page vous permettent d'ajouter des mises en page partagées aux pages sans qu'elles ne comprennent toutes l'intégralité d'un répertoire dans routes
.
We pourriez ajouter un +layout.svelte
fichier et quelques idiots <div>
bannière disant, "Hé, nous gérons les tâches". Mais faisons quelque chose de plus intéressant. Les mises en page peuvent définir load()
fonctions afin de fournir des données pour toutes les routes en dessous. Utilisons cette fonctionnalité pour charger nos balises — puisque nous utiliserons nos balises dans notre details
page — en plus de la list
page que nous avons déjà.
En réalité, forcer un groupe de mise en page à ne fournir qu'une seule donnée n'en vaut certainement pas la peine ; il est préférable de dupliquer ces données dans le load()
fonction pour chaque page. Mais pour cet article, cela fournira l'excuse dont nous avons besoin pour voir une nouvelle fonctionnalité SvelteKit !
Entrons d'abord dans notre list
la page +page.server.js
fichier et supprimez les balises de celui-ci.
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); return { todos, };
}
Notre page de liste devrait maintenant produire une erreur puisqu'il n'y a pas tags
chose. Corrigeons cela en ajoutant un +layout.server.js
fichier dans notre groupe de mise en page, puis définissez un load()
fonction qui charge nos balises.
import { getTags } from "$lib/data/todoData"; export function load() { const tags = getTags(); return { tags, };
}
Et, juste comme ça, notre page Liste s'affiche à nouveau !
Nous chargeons des données à partir de plusieurs emplacements
Mettons un point fin sur ce qui se passe ici:
- Nous avons défini un
load()
fonction pour notre groupe de mise en page, que nous avons mis en+layout.server.js
. - Cela fournit des données pour TOUTE des pages desservies par la mise en page - ce qui signifie dans ce cas nos pages Liste et Détails.
- Notre page Liste définit également un
load()
fonction qui va dans son+page.server.js
fichier. - SvelteKit fait le gros du travail en prenant les résultats de ces sources de données, en les fusionnant et en les rendant disponibles dans
data
.
Notre page Détails
Nous utiliserons notre page Détails pour modifier une tâche à faire. Tout d'abord, ajoutons une colonne au tableau de notre page Liste qui renvoie à la page Détails avec l'ID de l'élément de tâche dans la chaîne de requête.
<td><a href="/fr/details?id={t.id}">Edit</a></td>
Construisons maintenant notre page Détails. Tout d'abord, nous allons ajouter un chargeur pour saisir l'élément de tâche que nous modifions. Créer un +page.server.js
in /details
, avec ce contenu :
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, };
}
Notre chargeur est livré avec un url
propriété à partir de laquelle nous pouvons extraire des valeurs de chaîne de requête. Cela facilite la recherche de l'élément de tâche que nous modifions. Rendons cette tâche à faire, ainsi que la fonctionnalité pour la modifier.
SvelteKit possède de merveilleuses capacités de mutation intégrées, tant que vous utilisez des formulaires. Vous vous souvenez des formulaires ? Voici notre page Détails. J'ai élidé les styles par souci de brièveté.
<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>
Nous récupérons les balises comme auparavant à partir du chargeur de notre groupe de mise en page et l'élément de tâche à partir du chargeur de notre page. Nous saisissons le réel tag
objets de la liste de tâches des identifiants de balises, puis tout afficher. Nous créons un formulaire avec une entrée cachée pour l'ID et une entrée réelle pour le titre. Nous affichons les balises, puis fournissons un bouton pour soumettre le formulaire.
Si vous avez remarqué le use:enhance
, qui indique simplement à SvelteKit d'utiliser l'amélioration progressive et Ajax pour soumettre notre formulaire. Vous l'utiliserez probablement toujours.
Comment enregistrons-nous nos modifications ?
Notez le action="?/editTodo"
attribut sur le formulaire lui-même ? Cela nous indique où nous voulons soumettre nos données éditées. Pour notre cas, nous voulons soumettre à un editTodo
"action."
Créons-le en ajoutant ce qui suit au +page.server.js
fichier que nous avons déjà pour les détails (qui a actuellement un load()
fonction, pour saisir notre to-do):
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"); },
};
Les actions de formulaire nous donnent un request
objet, qui donne accès à notre formData
, qui a un get
méthode pour nos différents champs de formulaire. Nous avons ajouté cette entrée masquée pour la valeur ID afin que nous puissions la saisir ici afin de rechercher l'élément de tâche que nous modifions. Nous simulons un retard, appelons un nouveau updateTodo()
méthode, puis rediriger l'utilisateur vers la /list
page. Le updateTodo()
met simplement à jour nos données statiques ; dans la vraie vie, vous exécuteriez une sorte de mise à jour dans le magasin de données que vous utilisez.
export async function updateTodo(id, newTitle) { const todo = todos.find(t => t.id == id); Object.assign(todo, { title: newTitle });
}
Essayons. Nous allons d'abord accéder à la page Liste :
Maintenant, cliquons sur le bouton Modifier de l'un des éléments à faire pour afficher la page d'édition dans /details
.
Nous allons ajouter un nouveau titre :
Maintenant, cliquez sur Enregistrer. Cela devrait nous ramener à notre /list
page, avec le nouveau titre de la tâche appliqué.
Comment le nouveau titre est-il apparu comme ça? C'était automatique. Une fois que nous avons redirigé vers le /list
page, SvelteKit a automatiquement réexécuté tous nos chargeurs comme il l'aurait fait de toute façon. C'est l'avancée clé que les cadres d'application de nouvelle génération, comme SvelteKit, Remixet la
13 suivant apporter. Plutôt que de vous donner un moyen pratique de rendre les pages, puis de vous souhaiter bonne chance pour récupérer tous les points de terminaison dont vous pourriez avoir besoin pour mettre à jour les données, ils intègrent la mutation des données parallèlement au chargement des données, permettant aux deux de travailler en tandem.
Certaines choses que vous vous demandez peut-être…
Cette mise à jour de mutation ne semble pas trop impressionnante. Les chargeurs se relanceront chaque fois que vous naviguez. Et si nous n'avions pas ajouté de redirection dans notre action de formulaire, mais que nous étions restés sur la page actuelle ? SvelteKit effectuerait la mise à jour dans l'action de formulaire, comme avant, mais toujours réexécutez tous les chargeurs de la page en cours, y compris les chargeurs de la ou des présentations de page.
Pouvons-nous disposer de moyens plus ciblés pour invalider nos données ? Par exemple, nos balises n'ont pas été modifiées, donc dans la vraie vie, nous ne voudrions pas les interroger à nouveau. Oui, ce que je vous ai montré n'est que le comportement par défaut des formulaires dans SvelteKit. Vous pouvez désactiver le comportement par défaut en fournir un rappel à use:enhance
. Ensuite, SvelteKit fournit un manuel fonctions d'invalidation.
Charger des données sur chaque navigation est potentiellement coûteux et inutile. Puis-je mettre en cache ces données comme je le fais avec des outils comme react-query
? Oui, juste différemment. SvelteKit vous permet de définir (puis de respecter) les en-têtes de contrôle de cache que le Web fournit déjà. Et je couvrirai les mécanismes d'invalidation du cache dans un article de suivi.
Tout ce que nous avons fait tout au long de cet article utilise des données statiques et modifie les valeurs en mémoire. Si vous devez tout rétablir et recommencer, arrêtez et redémarrez le npm run dev
Processus de nœud.
Emballage en place
Nous avons à peine effleuré la surface de SvelteKit, mais j'espère que vous en avez vu assez pour vous enthousiasmer. Je ne me souviens pas de la dernière fois où j'ai trouvé le développement Web aussi amusant. Avec des éléments tels que le regroupement, le routage, le SSR et le déploiement, tous gérés de manière prête à l'emploi, je passe plus de temps à coder qu'à configurer.
Voici quelques ressources supplémentaires que vous pouvez utiliser lors des prochaines étapes d'apprentissage de SvelteKit :
- Contenu propulsé par le référencement et distribution de relations publiques. Soyez amplifié aujourd'hui.
- Platoblockchain. Intelligence métaverse Web3. Connaissance Amplifiée. Accéder ici.
- La source: https://css-tricks.com/getting-started-with-sveltekit/
- 1
- 10
- 100
- 11
- 7
- 9
- 98
- a
- Capable
- Qui sommes-nous
- à propos de ça
- accès
- Compte
- Action
- actes
- Adam
- ajoutée
- ajout
- propos
- admin
- Avancée
- affecter
- Tous
- Permettre
- aux côtés de
- déjà
- toujours
- montant
- ainsi que les
- Une autre
- répondre
- chacun.e
- appli
- Application
- applications
- appliqué
- autour
- tableau
- article
- artificiel
- attribué
- Automatique
- automatiquement
- disponibles
- attendre
- RETOUR
- fond
- bannière
- barre
- Essentiel
- before
- LES MEILLEURS
- Améliorée
- jusqu'à XNUMX fois
- Bit
- Noir
- Blog
- Blogue
- Bleu
- Box
- apporter
- navigateur
- bogues
- construire
- construit
- intégré
- bouton (dans la fenêtre de contrôle qui apparaît maintenant)
- Cache
- Appelez-nous
- Appels
- capacités
- maisons
- Assurément
- difficile
- en changeant
- clair
- code
- Codage
- Couleur
- Colonne
- comment
- Commun
- Compétitions
- composant
- composants électriques
- conférences
- NOUS CONTACTER
- Connecter les
- Console
- contenu
- Pratique
- pourriez
- Cours
- couvrant
- Housses
- engendrent
- créée
- La création
- Courant
- Lecture
- données
- Base de données
- Réglage par défaut
- Définit
- retarder
- retards
- déploiement
- Conception
- détails
- dev
- Développement
- DID
- Commande
- Ne fait pas
- faire
- Ne pas
- chacun
- ailleurs
- assez
- Tout
- intégralité
- erreur
- etc
- Pourtant, la
- Chaque
- peut
- exemple
- excité
- Excitation
- existe
- cher
- Exporter
- réalisable
- Fonctionnalité
- few
- Des champs
- Déposez votre dernière attestation
- Fichiers
- finalement
- fin
- Incendie
- Prénom
- Fixer
- plat
- Abonnement
- toujours
- formulaire
- le format
- document
- trouvé
- cadres
- de
- plein
- amusement
- fonction
- fonctions
- obtenez
- obtention
- Donner
- Don
- Global
- Go
- objectif
- Goes
- aller
- saisir
- Réservation de groupe
- Groupes
- arriver
- Dur
- têtes
- vous aider
- ici
- caché
- hiérarchie
- de haut niveau
- détient
- Avec optimisme
- Horizontal
- Comment
- HTML
- HTTPS
- MAUVAIS
- imagination
- importer
- importance
- impressionnant
- in
- Y compris
- initiale
- contribution
- plutôt ;
- intégrer
- intéressant
- Introduction
- IT
- articles
- lui-même
- JavaScript
- ACTIVITES
- Nom de famille
- Nouveautés
- Disposition
- apprentissage
- Allons-y
- Niveau
- Li
- VIE
- lumière
- Probable
- Gauche
- Liste
- le travail
- charge
- chargeur
- chargement
- charges
- Location
- Style
- LOOKS
- rechercher
- chance
- machinerie
- a prendre une
- FAIT DU
- Fabrication
- les gérer
- Manuel
- Marge
- Matière
- veux dire
- Mémoire
- seulement
- fusion
- méthode
- pourrait
- l'esprit
- Module
- PLUS
- Bougez
- en mouvement
- plusieurs
- prénom
- Nommé
- nav
- NAVIGUER
- Navigation
- nécessaire
- Besoin
- Nouveauté
- next
- nœud
- Ordinaire
- nombre
- objet
- objets
- ONE
- de commander
- Autre
- autrement
- propre
- particulier
- chemin
- Effectuer
- en particulier pendant la préparation
- pièce
- pièces
- espace réservé
- Platon
- Intelligence des données Platon
- PlatonDonnées
- Point
- Post
- Poteaux
- l'éventualité
- Préparer
- Problème
- processus
- produire
- progressif
- Projet
- promet
- propriété
- protégé
- fournir
- fournit
- RÉSERVES
- mettre
- question
- raw
- Lire
- réal
- la vie réelle
- Réalité
- Rouge
- réorienter
- Indépendamment
- rester
- rappeler
- supprimez
- rendu
- rend
- nécessaire
- Resources
- Résultats
- retourner
- retour
- Retours
- revenir
- Rich
- racine
- Itinéraire
- routes
- Courir
- pour le running
- même
- Épargnez
- voir
- sert
- set
- Shadow
- Partager
- commun
- devrait
- montrer
- étapes
- simplement
- depuis
- unique
- Glissement
- So
- quelques
- quelque chose
- Sources
- passer
- Commencer
- j'ai commencé
- séjourné
- Étapes
- Arrêter
- soumettre
- Les soutiens
- Surface
- combustion propre
- table
- TAG
- Prenez
- prise
- discutons-en
- tandem
- des campagnes marketing ciblées,
- raconte
- modèle
- terminal
- Les
- des choses
- tout au long de
- fiable
- Titre
- à
- ensemble
- trop
- les outils
- Tour
- traiter
- oui
- TOUR
- Manuscrit
- ui
- sous
- Mises à jour
- Actualités
- URL
- us
- utilisé
- Utilisateur
- Plus-value
- Valeurs
- divers
- via
- Voir
- attendez
- voulu
- façons
- web
- composants Web
- Développement Web
- Quoi
- qui
- blanc
- sera
- gagner
- sans
- merveilleux
- activités principales
- vos contrats
- vaut
- pourra
- écrire
- Vous n'avez
- Votre
- zéphyrnet