Skip to main content
Svelte基础
介绍
响应
属性Props
逻辑表达式
事件
绑定
Classes和样式
动作Actions
转场
Svelte高阶
响应式进阶
内容复用
动画
高级绑定
Advanced transitions
Context API
Special elements
<script module>
Next steps
Basic SvelteKit
Introduction
Routing
Loading data
Headers and cookies
Shared modules
Forms
API routes
$app/state
Errors and redirects
Advanced SvelteKit
Hooks
Page options
Link options
Advanced routing
Advanced loading
Environment variables
Conclusion

You can also add handlers that mutate data, such as POST. In most cases, you should use form actions instead — you’ll end up writing less code, and it’ll work without JavaScript, making it more resilient.

Inside the keydown event handler of the ‘add a todo’ <input>, let’s post some data to the server:

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 = '';
	}}
/>

Here, we’re posting some JSON to the /todo API route — using a userid from the user’s cookies — and receiving the id of the newly created todo in response.

Create the /todo route by adding a src/routes/todo/+server.js file with a POST handler that calls createTodo in 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 });
}

As with load functions and form actions, the request is a standard Request object; await request.json() returns the data that we posted from the event handler.

We’re returning a response with a 201 Created status and the id of the newly generated todo in our database. Back in the event handler, we can use this to update the 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 = '';
	}}
/>

You should only update data in such a way that you’d get the same result by reloading the page. The data prop is not deeply reactive, so you need to replace it — mutations like data.todos = todos will not cause a re-render.

Edit this page on GitHub

<script>
let { data } = $props();
</script>

<div class="centered">
<h1>todos</h1>

<label>
add a todo:
<input
type="text"
autocomplete="off"
onkeydown={async (e) => {
if (e.key !== 'Enter') return;

const input = e.currentTarget;
const description = input.value;
// TODO handle submit

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 handle change
booting webcontainer