表单操作
约 995 字大约 3 分钟
2026-09-23
标准表单
所有表单操作, 需要被注册在 xxx.server.ts 下, 不能直接注册在 xxx.ts 下, 因为表单操作是需要在服务器端执行的, 所以必须在服务器端注册.
/src/routes/login/+page.svelte
<script lang="ts">
import type { PageProps } from './$types';
// 此处的form为后端传递给前端的信息
let { data, form }: PageProps = $props();
</script>
{#if form}
{#if form.success === false}
<div
class="fixed top-4 left-1/2 z-50 w-full max-w-md -translate-x-1/2 rounded-lg bg-red-100 p-4 text-sm text-red-700 dark:bg-red-900 dark:text-red-300"
>
{form.message}
</div>
{:else}
<div
class="fixed top-4 left-1/2 z-50 w-full max-w-md -translate-x-1/2 rounded-lg bg-green-100 p-4 text-sm text-green-700 dark:bg-green-900 dark:text-green-300"
>
{form.message}
</div>
{/if}
{/if}
<form method="POST" action="?/login">
Username: <input type="text" name="username" />
<br />
Password: <input type="text" name="password" />
<br />
<button type="submit">Login</button>
</form>/src/routes/login/+page.server.ts
import { type Actions, fail } from '@sveltejs/kit'
export const actions = {
login: async ({ request, cookies }) => {
const data = await request.formData()
const username = data.get('username')
const password = data.get('password')
if (!username || !password) {
// 这里就是返回给前端的内容
return fail(400, { success: false, message: 'Username and password are required' })
}
if (username !== 'admin' || password !== 'password') {
return fail(401, { success: false, message: 'Invalid username or password' })
}
cookies.set('session', 'valid-session-token', { path: '/' })
return { success: true, message: 'Login successful' }
}
} satisfies Actions增强表单
在 标准表单 的基础上, 我们可以使用 enhance 来增强表单的功能, 让表单在提交时不会刷新页面, 而是通过 fetch 来提交表单数据, 并且可以在前端处理返回的数据.
<script lang="ts">
import {enhance} from '$app/forms';
</script>
<script lang="ts">
import type { PageProps } from './$types';
import { enhance } from '$app/forms';
let { form }: PageProps = $props();
</script>
{#if form}
... 省略
{/if}
<!-- 在表单上增加 use:enhance 即可让表单变成网络请求, 而不是原生的表单, 这样用户体验会更好, 不会出现闪烁的情况 -->
<form method="POST" action="?/login" use:enhance>
Username: <input type="text" name="username" />
<br />
Password: <input type="text" name="password" />
<br />
<button type="submit">Login</button>
</form>在增强表单上还可以使用一个自定义函数, 这个函数会在表单提交时被调用, 并且可以在这个函数中处理表单提交的逻辑, 例如可以在这个函数中进行表单验证, 或者在这个函数中进行表单提交后的处理逻辑.
一般用来实现加载动画之类的功能。
<script lang="ts">
import { enhance, applyAction } from '$app/forms';
import type { PageProps } from './$types';
let { form }: PageProps = $props();
</script>
<form
method="POST"
use:enhance={({ formElement, formData, action, cancel, submitter }) => {
// `formElement` is this `<form>` element
// `formData` is its `FormData` object that's about to be submitted
// `action` is the URL to which the form is posted
// calling `cancel()` will prevent the submission
// `submitter` is the `HTMLElement` that caused the form to be submitted
return async ({ result, update }) => {
// `result` is an `ActionResult` object
// `update` is a function which triggers the default logic that would be triggered if this callback wasn't set
if (result.type === 'redirect') {
goto(result.location);
} else {
// 将获取到的结果应用到表单上, form 变量就可以获取到内容的变化
await applyAction(result);
}
};
}}
>我们也可以自己来实现表单的提交逻辑, 例如我们可以在表单提交时, 使用 fetch 来提交表单数据, 并且可以在前端处理返回的数据。
<script lang="ts">
import { invalidateAll, goto } from '$app/navigation';
import { applyAction, deserialize } from '$app/forms';
import type { PageProps } from './$types';
import type { ActionResult } from '@sveltejs/kit';
let { form }: PageProps = $props();
async function handleSubmit(event: SubmitEvent & { currentTarget: EventTarget & HTMLFormElement}) {
event.preventDefault();
const data = new FormData(event.currentTarget, event.submitter);
const response = await fetch(event.currentTarget.action, {
method: 'POST',
body: data
});
const result: ActionResult = deserialize(await response.text());
if (result.type === 'success') {
// rerun all `load` functions, following the successful update
await invalidateAll();
}
applyAction(result);
}
</script>
<form method="POST" onsubmit={handleSubmit}>
<!-- content -->
</form>