620 Svelte/SvelteKit 前端开发
一句话概述:Svelte 是"编译型"前端框架,代码在构建时编译成原生 JS,不需要运行时库,性能极高且代码量极少,SvelteKit 是其全栈框架,类似 React 的 Next.js。
核心知识点速查表
| 知识点 | 说明 |
|---|
| 最新版本 | Svelte 5.45+(2026年) |
| 全栈框架 | SvelteKit 2.57+(基于 Vite 7) |
| 核心特性 | Runes 响应式、编译时优化、零运行时 |
| 新特性 | Attachments、Remote Functions、Async SSR |
| 打包工具 | Vite 7(SvelteKit 内置) |
| 适用场景 | 高性能Web应用、交互式UI、全栈应用 |
一、安装配置
# 创建 SvelteKit 项目(推荐)
npx sv create my-app # 交互式创建(选择模板和配置)
cd my-app
npm install # 安装依赖
npm run dev # 启动开发服务器 http://localhost:5173
1.1 项目结构
my-app/
├── src/
│ ├── routes/ # 基于文件系统的路由
│ │ ├── +page.svelte # 首页 → /
│ │ ├── +layout.svelte # 根布局
│ │ ├── about/
│ │ │ └── +page.svelte # 关于页 → /about
│ │ └── blog/
│ │ ├── +page.svelte # 博客列表 → /blog
│ │ └── [slug]/
│ │ └── +page.svelte # 动态路由 → /blog/my-post
│ ├── lib/ # 共享代码(可用 $lib 别名导入)
│ └── app.html # HTML 模板
├── static/ # 静态资源
├── svelte.config.js # Svelte 配置
└── vite.config.ts # Vite 配置
二、基本使用
2.1 组件基础(Svelte 5 Runes)
<!-- src/routes/+page.svelte -->
<script>
// Svelte 5 使用 Runes(符文)系统做响应式
let count = $state(0); // $state:声明响应式变量(白话:值变了,页面自动更新)
let doubled = $derived(count * 2); // $derived:计算属性(白话:自动跟着 count 变)
function increment() {
count++; // 直接修改,页面自动更新(不需要 setState)
}
</script>
<h1>计数器</h1>
<button onclick={increment}>
点击次数: {count},双倍: {doubled}
</button>
<style>
/* 样式自动局部作用域(不会影响其他组件) */
button {
padding: 8px 16px;
background: #ff3e00; /* Svelte 标志色 */
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
2.2 Props 与组件通信
<!-- src/lib/components/UserCard.svelte -->
<script>
// Svelte 5 用 $props() 接收属性
let { name, email, age = 18 } = $props(); // age 有默认值
// 白话:父组件传什么,这里就接什么
</script>
<div class="card">
<h2>{name}</h2>
<p>邮箱: {email}</p>
<p>年龄: {age}</p>
</div>
<!-- 父组件中使用 -->
<!-- <UserCard name="张三" email="zhang@example.com" age={25} /> -->
2.3 条件与循环
<script>
let items = $state(['苹果', '香蕉', '橙子']); // 响应式数组
let show = $state(true); // 控制显隐
</script>
<!-- 条件渲染 -->
{#if show}
<p>内容可见</p>
{:else}
<p>内容隐藏</p>
{/if}
<!-- 列表循环 -->
<ul>
{#each items as item, index (item)}
<li>{index + 1}. {item}</li>
{/each}
</ul>
<!-- 异步数据 -->
{#await fetchData()}
<p>加载中...</p>
{:then data}
<p>数据: {data}</p>
{:catch error}
<p>出错: {error.message}</p>
{/await}
2.4 Effects(副作用)
<script>
let count = $state(0);
// $effect:当依赖变化时自动执行(白话:监听变化做事情)
$effect(() => {
console.log(`count 变成了: ${count}`); // count 变化时自动打印
// 返回清理函数(可选)
return () => {
console.log('清理上一次的 effect');
};
});
</script>
三、SvelteKit 路由与数据
3.1 页面数据加载
// src/routes/blog/+page.server.ts(服务端加载数据)
// 白话:这个文件只在服务器运行,可以安全地连数据库、调用 API
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ fetch }) => {
const res = await fetch('https://api.example.com/posts'); // 服务端获取数据
const posts = await res.json();
return {
posts // 返回的数据传给页面组件
};
};
<!-- src/routes/blog/+page.svelte -->
<script>
let { data } = $props(); // 接收 load 函数返回的数据
</script>
<h1>博客列表</h1>
{#each data.posts as post}
<article>
<h2><a href="/blog/{post.slug}">{post.title}</a></h2>
<p>{post.excerpt}</p>
</article>
{/each}
// src/routes/login/+page.server.ts
import type { Actions } from './$types';
import { fail, redirect } from '@sveltejs/kit';
export const actions: Actions = {
default: async ({ request }) => {
const data = await request.formData(); // 获取表单数据
const email = data.get('email');
const password = data.get('password');
if (!email || !password) {
return fail(400, { error: '请填写所有字段' }); // 返回错误
}
// 验证逻辑...
throw redirect(303, '/dashboard'); // 登录成功,重定向
}
};
<!-- src/routes/login/+page.svelte -->
<script>
let { form } = $props(); // 接收表单操作的返回值
</script>
<form method="POST">
{#if form?.error}
<p class="error">{form.error}</p>
{/if}
<input name="email" type="email" placeholder="邮箱" />
<input name="password" type="password" placeholder="密码" />
<button type="submit">登录</button>
</form>
3.3 API 路由
// src/routes/api/users/+server.ts
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
export const GET: RequestHandler = async () => {
const users = [
{ id: 1, name: '张三' },
{ id: 2, name: '李四' }
];
return json(users); // 返回 JSON 响应
};
export const POST: RequestHandler = async ({ request }) => {
const body = await request.json(); // 获取请求体
return json({ id: 3, ...body }, { status: 201 });
};
四、高级用法
4.1 Stores(全局状态管理)
// src/lib/stores/auth.ts
import { writable } from 'svelte/store';
// writable:可读可写的全局状态(白话:所有组件共享的变量)
export const user = writable(null); // 初始值为 null
export const isLoggedIn = writable(false);
// 自定义 store
function createCounter() {
const { subscribe, set, update } = writable(0);
return {
subscribe, // 订阅变化
increment: () => update(n => n + 1),
decrement: () => update(n => n - 1),
reset: () => set(0)
};
}
export const counter = createCounter();
<!-- 在组件中使用 store -->
<script>
import { user } from '$lib/stores/auth';
// 用 $ 前缀自动订阅(白话:$user 会自动跟着 store 变化更新)
</script>
<p>当前用户: {$user?.name ?? '未登录'}</p>
4.2 Svelte 5 Attachments(新特性)
<script>
import { createTooltip } from '$lib/actions/tooltip';
// Attachments:声明式地给 DOM 元素附加行为
// 白话:像给元素"贴标签"一样添加功能
const tooltip = createTooltip('这是提示文字');
</script>
<button {@attach tooltip}>
悬停查看提示
</button>
4.3 页面过渡动画
<script>
import { fade, fly, slide } from 'svelte/transition'; // 内置过渡动画
let visible = $state(true);
</script>
<button onclick={() => visible = !visible}>切换</button>
{#if visible}
<!-- 淡入淡出 -->
<p transition:fade={{ duration: 300 }}>淡入淡出效果</p>
<!-- 从上方飞入 -->
<p in:fly={{ y: -50, duration: 500 }} out:fade>飞入效果</p>
<!-- 滑动 -->
<p transition:slide>滑动效果</p>
{/if}
五、常见报错与解决
| 问题 | 解决 |
|---|
$state is not defined | 确保使用 Svelte 5+,旧版本不支持 Runes |
| 水合错误(Hydration mismatch) | 确保服务端和客户端渲染结果一致 |
Cannot use $state in .ts files | $state 只能在 .svelte 或 .svelte.ts 文件中使用 |
| 路由404 | 检查 src/routes/ 目录下文件名是否正确(必须是 +page.svelte) |
六、速查表
| 操作 | 代码/说明 |
|---|
| 创建项目 | npx sv create my-app |
| 开发模式 | npm run dev |
| 构建 | npm run build |
| 响应式变量 | let x = $state(0) |
| 计算属性 | let y = $derived(x * 2) |
| 副作用 | $effect(() => { ... }) |
| 接收Props | let { name } = $props() |
| 条件渲染 | {#if}{:else}{/if} |
| 列表循环 | {#each items as item}{/each} |
| 页面数据 | +page.server.ts 的 load 函数 |
| 表单操作 | +page.server.ts 的 actions |
| API路由 | +server.ts 的 GET/POST |
七、同类工具对比
| 特性 | Svelte/Kit | React/Next | Vue/Nuxt | Solid |
|---|
| 运行时 | 无(编译) | ~40KB | ~33KB | ~7KB |
| 响应式 | Runes | Hooks | Composition | Signals |
| 学习曲线 | 低 | 中 | 中 | 低 |
| 生态 | 增长中 | 最大 | 大 | 小 |
| 性能 | 极高 | 高 | 高 | 极高 |
| SSR | SvelteKit | Next.js | Nuxt | SolidStart |
选型建议:追求极致性能和简洁代码选 Svelte;大团队/丰富生态选 React;渐进式需求选 Vue。
参考资料:Svelte 官方文档 | SvelteKit 文档 | GitHub