Bases de Svelte
Introduction
Liaisons
Classes et styles
Svelte avancé
Réutiliser du contenu
Mouvements
Liaisons avancées
Transitions avancées
API de contexte
Éléments spéciaux
<script module>
Next steps
Bases de SvelteKit
Introduction
Routing
Chargement de données
En-têtes et cookies
Modules partagés
Formulaires
$app/state
Erreurs et redirections
SvelteKit avancé
Options de page
Options de lien
Routing avancé
Chargement avancé
Variables d’environnement
Conclusion
Vous pouvez également ajouter des gestionnaires qui mutent les données, comme POST
. Dans la
plupart des cas, vous devriez plutôt utiliser les actions de formulaire — vous
écrirez moins de code, et cela fonctionnera sans JavaScript, rendant votre application plus
résiliente.
Dans le gestionnaire d’évènement keydown
de l’<input>
“ajouter une tâche”, envoyons des données
au serveur :
<input
type="text"
autocomplete="off"
onkeydown={async (e) => {
if (e.key !== 'Enter') return;
const input = e.currentTarget;
const description = input.value;
const response = await fetch('/todo', {
method: 'POST',
body: JSON.stringify({ description }),
headers: {
'Content-Type': 'application/json'
}
});
input.value = '';
}}
/>
Ici, nous envoyons du JSON à la route d’API /todo
— en utilisant le userid
venant des cookies de
l’utilisateur — et nous recevons en réponse l’id
de la nouvelle tâche créée.
Créez la route /todo
en ajoutant un fichier src/routes/todo/+server.js
avec un gestionnaire
POST
qui appelle createTodo
importé depuis src/lib/server/database.js
:
import { json } from '@sveltejs/kit';
import * as database from '$lib/server/database.js';
export async function POST({ request, cookies }) {
const { description } = await request.json();
const userid = cookies.get('userid');
const { id } = await database.createTodo({ userid, description });
return json({ id }, { status: 201 });
}
Comme avec les fonctions load
et les actions de formulaire, la request
est un objet
Request standard ; await request.json()
fournit les données que nous avons envoyées depuis le gestionnaire d’évènement.
Nous renvoyons une réponse avec un statut 201 Created ainsi que l’id
de la
nouvelle tâche créée dans notre base. En revenant au niveau du gestionnaire d’évènement, nous
pouvons utiliser cette valeur pour mettre à jour la page :
<input
type="text"
autocomplete="off"
onkeydown={async (e) => {
if (e.key !== 'Enter') return;
const input = e.currentTarget;
const description = input.value;
const response = await fetch('/todo', {
method: 'POST',
body: JSON.stringify({ description }),
headers: {
'Content-Type': 'application/json'
}
});
const { id } = await response.json();
const todos = [...data.todos, {
id,
description
}];
data = { ...data, todos };
input.value = '';
}}
/>
Vous devriez toujours uniquement mettre à jour
data
de sorte à récupérer le même résultat que si vous aviez rechargé la page. La propdata
n’est pas profondément réactive, ce qui implique que vous devez la remplacer par une nouvelle valeur — les mutations commedata.todos = todos
ne vont pas provoquer de re-rendu.
Modifier cette page sur Github
<script>
let { data } = $props();
</script>
<div class="centered">
<h1>à faire</h1>
<label>
ajouter une tâche :
<input
type="text"
autocomplete="off"
onkeydown={async (e) => {
if (e.key !== 'Enter') return;
const input = e.currentTarget;
const description = input.value;
// TODO gérer la soumission
input.value = '';
}}
/>
</label>
<ul class="todos">
{#each data.todos as todo (todo.id)}
<li>
<label>
<input
type="checkbox"
checked={todo.done}
onchange={async (e) => {
const done = e.currentTarget.checked;
// TODO gérer l'édition
}}
/>
<span>{todo.description}</span>
<button
aria-label="Mark as complete"
onclick={async (e) => {
// TODO gérer la suppression
}}
></button>
</label>
</li>
{/each}
</ul>
</div>
<style>
.centered {
max-width: 20em;
margin: 0 auto;
}
label {
display: flex;
width: 100%;
}
input[type="text"] {
flex: 1;
}
span {
flex: 1;
}
button {
border: none;
background: url(./remove.svg) no-repeat 50% 50%;
background-size: 1rem 1rem;
cursor: pointer;
height: 100%;
aspect-ratio: 1;
opacity: 0.5;
transition: opacity 0.2s;
}
button:hover {
opacity: 1;
}
</style>