Svelte 5 出了快一年,为什么你还在用 4 的写法?
如果你还在用 Svelte 4 的思路写 Svelte 5 代码,只能说——你并不是一个人,但时间不等人。
Svelte 5 正式发布快一年了,最大变化不是语法糖,是底层响应式系统完全重写。Svelte 4 用的是类似 Vue 2 的「隐形 reactivity」——声明式赋值,框架自动追踪依赖。但 Svelte 5 换成了 Runes API,显式声明响应式变量,原理接近 Solid.js。
这个变化让很多老 Svelte 开发者写代码时出现了「肌肉记忆冲突」——看到 `$:` 下意识就想用,但 Svelte 5 已经不支持了。
三个核心 Runes,看完就会用
1. $state —— 替代所有响应式变量
// Svelte 4
let count = 0;
let user = null;
// Svelte 5
let count = $state(0);
let user = $state(null);
2. $derived —— 替代 $: doubleCount = count * 2
// 简单形式
let doubled = $derived(count * 2);
// 复杂逻辑用 $derived.by()
let summary = $derived.by(() => {
return items.filter(i => i.active).map(i => i.name).join(', ');
});
3. $effect —— 替代 onMount / $:
$effect(() => {
console.log('count changed:', count);
// 返回清理函数 = onDestroy 等效
return () => console.log('cleanup');
});
这三个搞定了,80% 的 Svelte 5 代码你都能写了。
Snippets 替代 Slot,书写更直观
Content Projection 模式也变了——Svelte 4 的 <slot /> 在 Svelte 5 变成了 {@render snippet()}。好处是指哪 render 哪,嵌套更清晰:
// Dialog 组件用法
let openCreateDialog = $state(false);
<Button onclick={() => (openCreateDialog = true)}>Create</Button>
<Dialog>
{#snippet children()}
<DialogContent>
<DialogHeader>
<DialogTitle>Create Organization</DialogTitle>
</DialogHeader>
<DialogFooter>
<Button variant="outline" onclick={() => (openCreateDialog = false)}>Cancel</Button>
<Button>Create</Button>
</DialogFooter>
</DialogContent>
{/snippet}
</Dialog>
一个很多人踩的坑:永远不要用原生 HTML 元素
这个 skill 里特别强调了这条规则:按钮用 <Button>,输入框用 <Input>,不要用 <button>、<input> 等原生元素。原因很简单——统一用 shadcn-svelte 组件,保证 Accessibility 和键盘交互行为一致。
这个规则看似死板,但在一个多人协作的代码库里,它避免了你每次都要检查 Focus 管理是否正确的问题。
这个 Skill 适合谁
- 正在从 Svelte 4 迁移到 Svelte 5 的开发者
- 已经在用 Svelte 5,但想确认「我的写法是不是对的」的人
- 需要给团队立 Svelte 5 代码规范的 Tech Lead
Skill 的 GitHub 来源是 Exceptionless——一个开源的错误追踪平台(Star 2.4k+,生产级项目),所以里面所有规范都经过实战验证,不是「理想状态下的建议」。
项目地址:https://github.com/exceptionless/Exceptionless
评论区
登录后可评论。