Svelte 5 响应式系统完全总结(2025 年最新版)
写得像普通 JavaScript,跑起来却自动响应式 —— 这就是 Svelte 5 的终极目标。
1. $state —— 核心响应式 API
| 写法 | 类型 | 是否深度响应式 | 修改方式触发更新? | 推荐度 |
|---|---|---|---|---|
let x = $state(值) | 深度响应式 | 是 | 直接改属性 / push 都行 | ★★★★★ |
let x = $state.raw(值) | 浅响应式 | 否 | 仅整体替换才更新 | ★★ |
$state.eager(值) | 深度响应式 | 是 | 强制立即刷新 UI | ★★ |
$state.snapshot(值) | 非响应式快照 | 否 | 从不更新 | ★★★ |
用法示例
<script>
// 普通深度响应式(99% 场景)
let count = $state(0);
let user = $state({ name: '张三', hobbies: ['coding'] });
// 浅响应式(大对象性能优化)
let hugeData = $state.raw([...]); // 改属性不更新
hugeData = newData; // 整体替换才更新
// 强制立即更新(导航高亮、loading 反馈)
let currentPath = $state.eager(location.pathname);
// 取快照(日志、JSON、传给第三方库)
console.log($state.snapshot(user));
</script>
2. 关键行为总结(必背!)
| 行为 | Svelte 5 表现 | 说明 |
|---|---|---|
| 直接修改对象属性 | 自动更新 | user.name = '李四' → 页面更新 |
| 数组 push / splice | 自动更新 | user.hobbies.push('游戏') 生效 |
| 解构赋值 | 丢失响应式 | const { name } = user → 永远是初始值 |
| console.log($state 对象) | 干净的普通对象 | 不会看到 Proxy |
| JSON.stringify($state 对象) | 直接可用 | 不报错 |
| 直接 export $state 变量 | 编译报错! | 禁止!必须用函数或 class 包装 |
3. 跨文件共享状态(最容易踩的坑!)
错误写法(编译直接报错)
// store.js 或 store.svelte.js
export let count = $state(0); // 禁止!!
export let user = $state({}); // 禁止!!
正确写法(两种推荐方式)
方式一:导出函数(最常用)
// stores/counter.js
let count = $state(0);
export function getCount() { return count; }
export function increment() { count += 1; }
export function setCount(v) { count = v; }
<script>
import { getCount, increment } from '$lib/stores/counter.js';
</script>
<div>{getCount()}</div>
<button on:click={increment}>+1</button>
方式二:用 class(优雅)
// stores/UserStore.js
class UserStore {
user = $state({ name: '张三', age: 18 });
updateName(name) { this.user.name = name; }
birthday() { this.user.age += 1; }
}
export const userStore = new UserStore();
<script>
import { userStore } from '$lib/stores/UserStore.js';
</script>
<div>{userStore.user.name}</div>
<button on:click={() => userStore.birthday()}>过生日</button>
4. 响应式原理(一句话开悟)
Svelte 5 不是“数据变了通知你”,而是“你读数据的时候,它会重新算一遍”。
let a = $state(1);
let b = $state(2);
let total = $derived(a + b); // 底层就是 getter:() => a + b
→ 你读 total 时,Svelte 自动重新执行 a + b,所以永远最新。
5. 常见坑 & 解决方案
| 场景 | 错误做法 | 正确做法 |
|---|---|---|
| 想共享状态 | export let count = $state(0) | 导出函数或 class |
| 想打印状态 | console.log(state) | console.log($state.snapshot(state)) |
| 想发请求 | JSON.stringify(state) | JSON.stringify($state.snapshot(state)) |
| 想立刻更新 UI(导航高亮) | 普通 $state | $state.eager(path) |
| 解构对象 | const { name } = user | 直接用 user.name |
| 大数组/对象不想深度追踪 | 普通 $state | $state.raw() + 整体替换 |
6. 终极建议(贴在桌子上)
// 99% 的情况:直接这样写
let x = $state(初始值);
// 跨文件共享:永远不要直接 export $state 变量!
// 用函数或 class 包装
// 打印/序列化:用 $state.snapshot()
// 立即刷新 UI:用 $state.eager()
// 大对象优化:用 $state.raw()
恭喜你!
你现在已经完全掌握了 Svelte 5 的响应式系统 ——
它是目前所有前端框架中最优雅、最接近原生 JavaScript、性能最高、坑最少的实现。
从此写代码:
- 像写普通 JS 一样自然
- 却拥有自动响应式的超能力
- 再也不用担心 Proxy、useState、依赖数组、immer、zustand…
欢迎来到前端的未来 —— Svelte 5!