Skip to main content
Bases de Svelte
Introduction
Réactivité
Props
Logique
Évènements
Liaisons
Classes et styles
Actions
Transitions
Svelte avancé
Réactivité avancée
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
Routes d’API
$app/state
Erreurs et redirections
SvelteKit avancé
Hooks
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 :

src/routes/+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'
			}
		});

		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 :

src/routes/todo/+server
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 :

src/routes/+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 prop data n’est pas profondément réactive, ce qui implique que vous devez la remplacer par une nouvelle valeur — les mutations comme data.todos = todos ne vont pas provoquer de re-rendu.

Modifier cette page sur Github

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<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>