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


GitHub: https://github.com/exceptionless/Exceptionless

评论区

0 条评论

登录后可评论。

江望 691 阅读