介绍
Svelte 是一个构建用户界面的框架。它和 React、Vue 一样用于开发 Web 应用,但有一个根本性的不同:Svelte 是一个编译器。
本教程基于最新的 Svelte 5.57.x,重点讲解全新的 Runes 响应式系统。
Svelte 与众不同在哪里
大多数前端框架(React、Vue)在运行时用虚拟 DOM 来协调状态与界面。Svelte 把大量工作提前到了编译期:
- 你的
.svelte文件被编译成直接操作 DOM 的、高度优化的原生 JavaScript。 - 没有虚拟 DOM 的 diff 开销,运行时体积极小。
- 结果就是:更小、更快、更简单的应用。
一句话理解
Svelte 把「框架」变成了「编译器」。你写的声明式代码,被编译成命令式的、直接操作 DOM 的高效代码。
Svelte 5 带来了什么
Svelte 5 是一次从底层重写的版本,最核心的变化是引入了 Runes(符文) —— 一种显式声明响应式的新机制。
| 维度 | Svelte 4 及更早 | Svelte 5(Runes) |
|---|---|---|
| 响应式状态 | 隐式,let 即响应式 | 显式,$state() |
| 派生值 | $: 标签语句 | $derived() |
| 副作用 | $: 或生命周期函数 | $effect() |
| 组件 props | export let | $props() |
| 事件 | on:click | onclick(属性) |
| 内容分发 | <slot> | {#snippet} / {@render} |
为什么要改成 Runes?
Svelte 4 的隐式响应式虽然简洁,但存在几个「诡异」之处:
- 响应式规则不直观:为什么改数组要用
todos = [...todos, newTodo]?为什么$:有时不按预期触发?这些「魔法」让人困惑。 - 只能在组件内使用:状态和响应式逻辑无法抽离到普通的
.js/.ts模块中复用。 - 细粒度不足:整个组件的更新粒度较粗。
Runes 用显式的函数调用解决了这些问题:
svelte
<script>
// 显式声明:这是一个响应式状态
let count = $state(0);
// 显式声明:这是一个依赖 count 的派生值
let doubled = $derived(count * 2);
// 显式声明:当依赖变化时运行副作用
$effect(() => {
console.log(`count 变成了 ${count}`);
});
</script>
<button onclick={() => count++}>
{count} 的两倍是 {doubled}
</button>Runes 的关键优势:
- 显式:一眼就能看出哪些值是响应式的、依赖关系是什么。
- 可组合、可复用:Runes 可以写在
.svelte.js/.svelte.ts模块里,在组件之外使用,方便构建可复用的状态逻辑。 - 细粒度:更精准的响应式追踪,带来更好的性能。
兼容性
Svelte 5 几乎完全向后兼容 Svelte 4。你可以渐进式迁移,两种写法可以在同一项目中共存。参见从 Svelte 4 迁移。
本教程如何使用
本站点的每一处「实时演示」卡片,都是真正的 Svelte 5 组件,用 Runes 编写并在浏览器中实时运行 —— 不是图片或动图。
下面就是一个最简单的计数器,试着点点看:
计数器 · $stateSvelte 5 · Live
svelte
<script>
let count = $state(0);
</script>
<button onclick={() => count--}>−</button>
<span>{count}</span>
<button onclick={() => count++}>+</button>学习路线
- 快速上手 —— 创建你的第一个 Svelte 5 项目
- 核心概念 · Runes —— 掌握
$state、$derived、$effect、$props - 组件与模板 —— 组件、模板语法、Snippets、事件
- 综合实战 —— 把所学知识串起来
- Runes API 速查 —— 随时查阅
准备好了吗?让我们开始动手。