这是 SvelteKit 最核心的心智之一。
很多前端新手会把数据加载理解成:
组件 mounted 后 fetch 一下
再 setState这在 SvelteKit 里太浅了。
SvelteKit 的 load 更像:
后台在场景真正亮相前
先把这个场景需要的道具、演员表、节目册调度到位它有两种主航道:
+page.ts / +layout.ts- 通用
load - 首次 SSR 时可在服务端跑,之后导航时也会在浏览器跑
- 通用
+page.server.ts / +layout.server.ts- 服务端专用
load - 可以访问数据库、私密环境变量、cookies、locals
- 服务端专用
最简化的判断法:
只要用到数据库、私密 token、用户会话、服务端鉴权
优先放 server load
只是在页面切换时根据 URL / fetch 公开数据 / 组合前后端已给的数据
可以放 universal load一个典型的通用 load:
// src/routes/plays/+page.ts
import type { PageLoad } from './$types';
export const load: PageLoad = async ({ url, fetch }) => {
const q = url.searchParams.get('q') ?? '';
const res = await fetch(`/api/plays?q=${encodeURIComponent(q)}`);
return {
q,
plays: await res.json()
};
};<!-- src/routes/plays/+page.svelte -->
<script lang="ts">
import type { PageProps } from './$types';
let { data }: PageProps = $props();
</script>
<h1>当前剧目</h1>
<form method="GET">
<input name="q" value={data.q} placeholder="搜索剧名" />
<button type="submit">筛选</button>
</form>
<ul>
{#each data.plays as play}
<li>
<a href="/plays/{play.slug}">{play.title}</a>
</li>
{/each}
</ul>这里有几个非常 SvelteKit 的点:
- 你可以直接使用原生
<form method="GET"> - URL 查询参数天然就是筛选状态
load会根据 URL 变化重新调度- 页面不是“挂载后才补数据”,而是数据与场景同时到位