Runes API 速查
本页汇总 Svelte 5 的核心 Runes 与相关 API,供随时查阅。所有示例基于 Svelte 5.57。
Runes 一览
| Rune | 作用 | 使用位置 |
|---|---|---|
$state | 声明响应式状态 | 组件 / .svelte.js |
$state.raw | 不被代理的原始响应式状态 | 组件 / .svelte.js |
$derived | 计算派生值 | 组件 / .svelte.js |
$derived.by | 用函数计算复杂派生值 | 组件 / .svelte.js |
$effect | 运行副作用(DOM 更新后) | 组件 |
$effect.pre | 运行副作用(DOM 更新前) | 组件 |
$props | 声明组件属性 | 组件 |
$bindable | 让 prop 支持双向绑定 | 组件(配合 $props) |
$inspect | 调试:追踪值变化 | 组件(开发用) |
$host | 获取自定义元素自身引用 | Web Component |
$state
js
let count = $state(0); // 基础类型
let user = $state({ name: '' }); // 对象:深度响应式
let items = $state([]); // 数组:push/splice 直接生效规则:
- 只能在组件顶层或
.svelte.js/.svelte.ts模块的函数中使用 - 直接赋值或调用变更方法都会触发更新
- 用 Proxy 实现深度响应式
$state.raw
js
let data = $state.raw(bigObject); // 不代理内部
data = { ...data, changed: true }; // 必须整体替换才更新适用:性能敏感的大对象、外部库实例、不可变数据。
$derived / $derived.by
js
// 单表达式
const doubled = $derived(count * 2);
// 多语句
const summary = $derived.by(() => {
const total = items.reduce((s, i) => s + i.price, 0);
return total > 100 ? '大额' : '小额';
});规则:
- 自动追踪依赖,仅在依赖变化时重算
- 只读,不可赋值
- 可依赖其他
$derived,形成派生链
$effect / $effect.pre
js
// DOM 更新后运行
$effect(() => {
console.log(count);
return () => { /* 清理 */ };
});
// DOM 更新前运行
$effect.pre(() => {
console.log('即将更新');
});规则:
- 自动追踪依赖,挂载后首次运行,之后依赖变化时重跑
- 返回的函数用于清理(下次运行前 & 销毁时调用)
- 只用于副作用(DOM/存储/网络/定时器);计算值请用
$derived
$props
js
// 基础
let { title, count = 0 } = $props();
// 收集剩余
let { children, ...rest } = $props();
// TypeScript
let { title, count = 0 }: { title: string; count?: number } = $props();规则:
- 用解构语法声明
- 默认值直接在解构中给
- 取代 Svelte 4 的
export let
$bindable
js
// 子组件:可被父组件 bind 的 prop
let { value = $bindable('') } = $props();svelte
<!-- 父组件 -->
<Child bind:value={myState} />规则:
- 只能用于
$props()解构的默认值位置 - 不带
bind:时表现为普通 prop(用默认值初始化) - 带
bind:时父子双向同步
$inspect
js
$inspect(count); // 每次 count 变化时打印
$inspect('label', user); // 带标签规则:
- 仅在开发模式有效,生产构建中移除
- 快速调试响应式变化的利器
生命周期函数(svelte 包)
Svelte 5 提供函数式生命周期,从 svelte 导入:
| 函数 | 时机 |
|---|---|
onMount(fn) | 组件挂载后 |
onDestroy(fn) | 组件销毁前 |
js
import { onMount } from 'svelte';
onMount(() => {
console.log('组件已挂载');
return () => console.log('组件即将销毁'); // 清理
});TIP
很多原本用 onMount 的场景,现在用 $effect 更合适(尤其是依赖某些状态的初始化)。
挂载 API
js
import { mount, unmount, hydrate } from 'svelte';
// 客户端挂载
const app = mount(App, {
target: document.getElementById('app'),
props: { name: 'world' }
});
// 卸载
unmount(app);
// SSR hydration(服务端渲染场景)
const app2 = hydrate(App, { target, props });组件实例 API
Svelte 5 的组件实例上,方法/属性通过 $props 暴露。父组件可用 bind:this 获取实例引用:
svelte
<script>
import Child from './Child.svelte';
let child;
</script>
<Child bind:this={child} />
<button onclick={() => child.someMethod()}>调用子组件方法</button>常见 Runes 使用限制
注意这些限制
- Runes 不能在条件语句、循环、try/catch、或普通函数体内动态调用(
$state等必须在组件/模块顶层或函数顶部) - Runes 只能出现在
.svelte文件或.svelte.js/.svelte.ts文件中 $effect只能在组件初始化期间调用,不能在事件处理函数或异步回调里调用$derived的表达式应是纯函数,不要在里面产生副作用
官方参考
- Runes 总览:https://svelte.dev/docs/svelte/what-are-runes
$state:https://svelte.dev/docs/svelte/$state$derived:https://svelte.dev/docs/svelte/$derived$effect:https://svelte.dev/docs/svelte/$effect$props:https://svelte.dev/docs/svelte/$props$bindable:https://svelte.dev/docs/svelte/$bindable