跳到主要内容

Svelte 速查表实战:从 Svelte 语法到 runes 响应式的常用写法

一份给 Svelte 开发者的速查指南,讲清响应式声明、组件 props、事件、each 块和 stores,顺带和 React、Vue 对比,说明编译时框架为什么没有虚拟 DOM。

发布于 作者 李雷
#svelte #前端 #速查表 #svelte 5 #响应式

Svelte 速查表实战:从 Svelte 语法到 runes 响应式的常用写法

写 Svelte 最舒服的一点,是它在编译阶段就把组件拆成了精准的 DOM 更新指令。它没有运行时的虚拟 DOM 比对,组件代码经过编译器变成直接操作真实 DOM 的命令式 JavaScript。所以同样一个计数器,Svelte 打包出来的体积往往只有 React 同类实现的几分之一,运行时也省掉了 diff 这一层开销。

下面把日常最常查的几块语法过一遍,顺手放一份真实组件做参照。需要随手翻完整片段的时候,直接开 /zh/t/svelte-cheatsheet/ 搜关键词就行,60 多条都能拷贝。

响应式声明:从 $: 标记到 runes

Svelte 4 里,响应式靠 $: 标记。你写 $: doubled = count * 2,编译器就盯着 count,它变了 doubled 跟着重算。这个写法直觉,但它的执行顺序由代码位置决定,抽不进函数,放进 .js 模块也不生效。

Svelte 5 换成了 runes。let count = $state(0) 给变量加响应性,let doubled = $derived(count * 2) 做带缓存的派生值,$effect(() => …) 跑带自动依赖追踪的副作用。它显式、可组合,同一套 $state.svelte.ts 模块里也照样用。新代码就用 runes,旧的 $: 写法在 5 里还能编译,改到哪迁到哪即可。

组件 props 和事件

接收 props 现在统一走 $props():let { value, onSave } = $props(),带默认值和剩余参数都顺手。事件这块变化更大,Svelte 5 不再推 createEventDispatcher,而是直接把回调当 prop 传:子组件声明 let { onSelect } = $props(),父组件写 <Picker onSelect={(v) => …} />。这跟 React 一直以来的做法是一回事,类型也顺着回调签名自然流过去。

each 块和流程控制

模板里的循环用 {#each},记得带 keyed,否则列表重排时 Svelte 没法精准复用节点:

{#each items as item (item.id)}
  <li>{item.name}</li>
{/each}

{#if} 分支、{#await} 处理 promise、{#key} 强制重建,这几个块凑齐了日常模板逻辑的全部。

stores 仍然有用

runes 解决了组件内的响应式,但跨多个不相干组件共享状态时,store 还是标准答案:鉴权、主题、购物车这类全局数据。writablereadablederived$ 前缀的自动订阅,在 .svelte 文件里读 $count 时 Svelte 自动帮你订阅和解订阅。SvelteKit 的 $app/stores 也是 store,所以哪怕你一个都不自己写,也得懂这套协议。一个朴素的判断:该上 React Context 的用 store,是 useState 的料用 $state

一个真实的 Svelte 5 组件

把响应式声明、props、派生值和事件放进一段能跑的代码:

<script lang="ts">
  let { step = 1, onReach }: { step?: number; onReach?: (n: number) => void } = $props();

  let count = $state(0);
  let doubled = $derived(count * 2);

  $effect(() => {
    if (count >= 10) onReach?.(count);
  });
</script>

<button onclick={() => (count += step)}>
  点了 {count} 次,翻倍是 {doubled}
</button>

count 是响应式变量,doubled$derived 派生并带缓存,$effectcount 到 10 时回调父组件。整段没有任何 this、没有 hooks 规则的束缚,编译器会把它变成只更新那个按钮文本的精确指令。

我自己从 React 转过来时,最不适应的就是没有 useEffect 的依赖数组要写,$effect 里读到哪个响应式值就自动追踪哪个,漏写依赖导致 stale closure 的那类 bug 直接消失了。第一周写 Svelte 的体感,是代码比脑子里想的还短。

和 React、Vue 怎么对照

如果你已经熟悉别的框架,横向对照能省不少时间。回调 props 这套 React 早就在用;$state 对应 useState,store 对应 Context。Vue 开发者会觉得 $stateref,$derivedcomputed,模板指令的味道也接近。想系统比对就配合 React Hooks 速查Vue3 速查 一起看,三套响应式模型摆在一起,差异一目了然。配 TypeScript 写组件时,TypeScript 速查 也能随手翻类型写法。

编译时框架的本质,是把"框架运行时该干的活"提前到了构建阶段。没有虚拟 DOM,意味着浏览器里跑的就是为你这个组件量身定制的更新代码,而不是一套通用的 diff 引擎。这是 Svelte 在体积和速度上的底牌,也是它语法能这么干净的原因。

把上面这些写法存进收藏夹,真要查具体片段时回 /zh/t/svelte-cheatsheet/ 搜一下,比翻官方文档快得多。


Made by Toolora · Updated 2026-06-13