关于 svelte-reference
svelte-reference 是面向 Svelte 5 开发者的 API 参考技能,整理常用模块、指令、编译器配置及错误与警告说明。它还提供状态管理、过渡动画、列表动画和 action 的实践示例与注意事项。
主要功能
- 01汇总 store、action 和事件 API
- 02说明过渡、缓动与列表动画
- 03提供编译器配置和输出参考
- 04解释常见编译错误与运行时警告
- 05附带 API 示例及常见问题提示
适用场景
- 01查找 Svelte 模块的 API 签名
- 02实现组件过渡或列表重排动画
- 03选择 store 或 runes 管理状态
- 04诊断编译错误和运行时警告
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ full-stack-skills/ svelte-skills --skill svelte-reference安装后在 Claude Code 中输入/svelte-reference确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlexamples/in-out-animate.mdmotion.mdREADME.mdstore-patterns.mdtransition.mdtransitions-advanced.mduse-action.mdreferences/animations-reference.mdin-out-reference.mdmotion-reference.mdREADME.mdstore-reference.mdtransition-reference.mdtransitions-complete.mduse-action-reference.md详细介绍
Svelte API 参考(Svelte 5)
本技能是 Svelte 官方模块 API 的快速参考,包括 svelte/store、svelte/action、svelte/transition、svelte/animate、svelte/easing、svelte/events、svelte/compiler 及常见编译器/运行时错误代码。
何时使用此技能
当用户需要查阅 Svelte 特定模块的 API 签名、使用 transition / in / out / animate 指令、use: action、easing 函数、错误代码含义,或需要编译器配置时,使用本技能。
关键:svelte/store
import { writable, readable, derived, readonly, get } from 'svelte/store';
| 函数 | 签名 | 说明 |
|---|---|---|
writable | (initial, start?) => { subscribe, set, update } | 可写 store |
readable | (initial, start) => { subscribe } | 只读 store(值只能由内部 start 设置) |
derived | (stores, fn, initial?) => { subscribe } | 派生 store |
readonly | (store) => store | 返回只读版本(无 set / update) |
get | (store) => value | 非订阅获取值(同步,创建临时订阅) |
Store 合约
store = {
subscribe: (subscription: (value: any) => void) => (() => void),
set?: (value: any) => void
}
何时使用 Stores,何时使用 Runes
- 优先使用 runes(在
.svelte.js文件中使用$state)来实现共享状态和提取逻辑。 - 使用 stores 来处理复杂的异步数据流、手动控制更新,或使用 RxJS 风格的运算符。
writable 启动函数
writable(initial, start) — 当订阅者数量从 0 → 1 时(而非从 1 → 2),会调用 start 回调。返回一个 stop 函数,它会在订阅者数量从 1 → 0 时运行。start 回调还会接收一个 update 函数(除了 set),用于基于转换的更新。
derived 的形式
// single store
const doubled = derived(a, ($a) => $a * 2);
// array of stores
const sum = derived([a, b], ([$a, $b]) => $a + $b);
// async — second arg is `set`, third is `update`, third `derived` arg is initial value
const delayed = derived(a, ($a, set) => {
setTimeout(() => set($a), 1000);
}, 0);
// with cleanup — return a function from the callback
const tick = derived(frequency, ($frequency, set) => {
const id = setInterval(() => set(Date.now()), 1000 / $frequency);
return () => clearInterval(id);
}, 0);
get(store) 注意事项
它会创建临时订阅,读取值,然后取消订阅。避免在热点路径中使用。
关键:svelte/action(use: 指令)
Action 是在元素挂载时调用的函数,通过 use: 指令添加:
<script>
/** @type {import('svelte/action').Action} */
function myAction(node) {
// node: HTMLElement — runs once on mount (client only, not SSR)
$effect(() => {
// setup
return () => {
// teardown — runs on unmount
};
});
}
</script>
<div use:myAction>...</div>
说明
在 Svelte 5.29 及更高版本中,可以考虑改用
{@attach ...}——它更灵活,也更易组合。
带参数的 Action
参数不是响应式的——Action 只会在挂载时运行一次。可在内部使用 $effect 来响应参数变化。
<script>
/** @type {import('svelte/action').Action<HTMLInputElement, number>} */
function debounce(node, delay) {
$effect(() => {
const handler = () => setTimeout(() => node.dispatchEvent(new Event('done')), delay);
node.addEventListener('input', handler);
return () => node.removeEventListener('input', handler);
});
}
</script>
<input use:debounce={300} />
旧版 update / destroy 形式
<script>
/** @type {import('svelte/action').Action<HTMLDivElement, string>} */
function colorize(node, color) {
node.style.color = color;
return {
update(newColor) { node.style.color = newColor; },
destroy() { node.style.color = ''; }
};
}
</script>
<div use:colorize={'red'}>...</div>
新代码优先使用 $effect 形式。
类型标注——Action<Node, Parameter, Events>
<script lang="ts">
import type { Action } from 'svelte/action';
const gestures: Action<HTMLDivElement, undefined, {
onswipeleft: (e: CustomEvent) => void;
onswiperight: (e: CustomEvent) => void;
}> = (node) => {
// dispatch: node.dispatchEvent(new CustomEvent('swipeleft'));
};
</script>
<div use:gestures onswipeleft={next} onswiperight={prev}>...</div>
第三个类型参数可让模板中的 onswipeleft / onswiperight 通过类型检查。
关键:svelte/transition(transition: 指令)
<script>
import { fade, fly, slide, scale, blur, draw, crossfade } from 'svelte/transition';
</script>
{#if visible}
<div transition:fade={{ duration: 300, delay: 100 }}>fade</div>
<div transition:fly={{ y: 20, duration: 300 }}>fly</div>
<div transition:slide>slide</div>
<div transition:scale={{ start: 0.5, duration: 300 }}>scale</div>
<div transition:blur={{ amount: 10 }}>blur</div>
{/if}
transition: 是双向的——被中断时会反向运行。
内置过渡效果
| 函数 | 效果 | 关键参数 |
|---|---|---|
fade | 透明度 | duration |
fly | 位置飞入 | x、y、opacity |
slide | 滑动 | axis: 'x' | 'y' |
scale | 缩放 | start、opacity |
blur | 模糊 + 透明度 | amount |
draw | SVG 路径绘制 | speed 或 duration |
crossfade | 成对淡入淡出 | duration、fallback |
过渡参数
{
delay?: number, // ms before starting (default 0)
duration?: number, // ms (default 400)
easing?: function, // easing (default linear)
css?: (t, u) => string,// web animation CSS (preferred)
tick?: (t, u) => void // imperative (use only when CSS cannot)
}
在 intro 时,t 从 0 → 1 运行;在 outro 时,t 从 1 → 0 运行。u = 1 - t。在 t 传给 css / tick 之前,会应用缓动。css 和 tick 不能同时使用。
局部与全局
<div transition:fade>...</div>
<div transition:fade|global>...</div>
过渡事件
| 事件 | 触发时机 |
|---|---|
introstart | intro 动画开始前 |
introend | intro 动画结束后 |
outrostart | outro 动画开始前 |
outroend | outro 动画结束后 |
<div
transition:fly={{ y: 200, duration: 2000 }}
onintrostart={() => (status = 'intro started')}
onoutroend={() => (status = 'outro ended')}
>...</div>
自定义过渡函数
// @noErrors
transition = (
node: HTMLElement,
params: any,
options: { direction: 'in' | 'out' | 'both' }
) => {
delay?: number;
duration?: number;
easing?: (t: number) => number;
css?: (t: number, u: number) => string;
tick?: (t: number, u: number) => void;
}
如果函数返回的是一个函数(而不是对象),Svelte 会在下一个微任务中调用它——crossfade 就是用这种方式协调成对的过渡效果。
重要:in: 和 out:(独立过渡)
in: 和 out: 是单向的——中断时不会反转。如果在入场动画中途切换关闭代码块,正在进行的入场动画会被放弃,出场过渡会从 t=0 重新开始。
<script>
import { fade, fly } from 'svelte/transition';
let visible = $state(false);
</script>
{#if visible}
<div in:fly={{ y: 200 }} out:fade>...</div>
{/if}
| 指令 | 运行时机 | 中断时可反转? |
|---|---|---|
transition: | 进入或离开时 | 可以(中途反转) |
in: | 仅进入时 | 不可以(放弃) |
out: | 仅离开时 | 不可以(始终正向播放) |
当进入和退出动画在视觉上应有所不同时,使用 in: / out:。自定义过渡函数的第三个参数是 { direction: 'in' | 'out' | 'both' }。
重要:svelte/easing
import { cubicIn, cubicOut, cubicInOut, elasticOut, bounceOut } from 'svelte/easing';
| 缓动 | 说明 |
|---|---|
linear | 匀速 |
quadIn/quadOut/quadInOut | 二次 |
cubicIn/cubicOut/cubicInOut | 三次缓动 |
quartIn/quartOut/quartInOut | 四次 |
quintIn/quintOut/quintInOut | 五次 |
sineIn/sineOut/sineInOut | 正弦 |
expoIn/expoOut/expoInOut | 指数 |
circIn/circOut/circInOut | 圆 |
elasticIn/elasticOut/elasticInOut | 弹性 |
backIn/backOut/backInOut | 回退 |
bounceIn/bounceOut/bounceInOut | 弹跳 |
<div transition:fly={{ y: 100, easing: cubicOut }}>...</div>
重要:animate:(svelte/animate)
animate: 会在带键的 {#each} 代码块中,现有项的索引发生变化时运行,而不是在添加/移除项时运行。它必须放在带键 each 代码块的直接子元素上。
<script>
import { flip } from 'svelte/animate';
let items = $state(['apple', 'banana', 'cherry']);
</script>
{#each items as item (item)}
<li animate:flip={{ duration: 400, easing: quintOut }}>{item}</li>
{/each}
flip(FLIP 技术)
测量 from 和 to 边界矩形,应用反向 transform,然后再将其动画回初始状态。完整 API 请参阅 references/animations-reference.md。
flip(node, {
delay?: number,
duration?: number | (node, { from, to }) => number,
easing?: function
})
自定义动画函数
// @noErrors
animation = (
node: HTMLElement,
{ from: DOMRect, to: DOMRect },
params: any
) => {
delay?: number;
duration?: number;
easing?: (t: number) => number;
css?: (t: number, u: number) => string;
tick?: (t: number, u: number) => void;
}
from 和 to 分别是重排前后元素的边界矩形。计算距离、角度等,以驱动自定义效果:
<script>
import { cubicOut } from 'svelte/easing';
function whizz(node, { from, to }) {
const dx = from.left - to.left;
const dy = from.top - to.top;
const d = Math.sqrt(dx * dx + dy * dy);
return {
duration: Math.sqrt(d) * 120,
easing: cubicOut,
css: (t, u) => `transform: translate(${u * dx}px, ${u * dy}px) rotate(${t * 360}deg);`
};
}
</script>
{#each list as item (item)}
<div animate:whizz>{item}</div>
{/each}
animate: 不会在添加/移除项时运行——此时请结合使用 in: / out:。
重要:svelte/events
提供 on 函数,用于替代 addEventListener(正确处理事件委托和 stopPropagation):
<script>
import { on } from 'svelte/events';
const handler = on(node, 'click', (event) => {
// 正确处理委托和 stopPropagation
}, { passive: true });
</script>
重要:svelte/reactivity
$effect.tracking
$effect.tracking(); // boolean,是否在追踪上下文中
createSubscriber
创建订阅者(仅在追踪上下文中工作):
import { createSubscriber } from 'svelte/reactivity';
const subscriber = createSubscriber((track) => {
track(value); // 声明依赖
});
重要:编译器错误(常见)
| 代码 | 含义 | 解决方法 |
|---|---|---|
2304 | 未定义的引用 | 检查变量名拼写和导入 |
2322 | 目标元素不存在 | 检查 target selector |
2554 | 类型不匹配 | 检查 TypeScript 类型标注 |
2451 | 在非 effect 中修改 state | 不要在 $effect 中直接赋值 $state |
7006 | 参数类型错误 | 检查函数签名 |
重要:运行时警告(常见)
| 代码 | 含义 | 解决方法 |
|---|---|---|
ownership_invalid_mutation | 修改了非自有状态 | 不要直接修改 prop,使用 $bindable |
await_waterfall | await 依赖链导致性能问题 | 重构数据获取逻辑 |
state_teardown | 尝试在销毁后更新 | 确保组件未卸载后再访问 |
重要:svelte/compiler
配置项
import { compile } from 'svelte/compiler';
const result = compile(source, {
filename: 'App.svelte',
generate: 'dom', // 'dom' | 'ssr' | false
name: 'Component', // 导出名
format: 'esm', // 'esm' | 'cjs'
sveltePath: 'svelte', // svelte 包路径
dev: true, // 开发模式(添加检查)
css: 'injected', // CSS 注入方式
runes: false, // 强制 Legacy Mode
// ...
});
compile 输出
result.js.code; // 编译后的 JS
result.css.code; // 编译后的 CSS(如有)
result.warnings; // 警告列表
result.stats; // 编译统计
快速修复
| 问题 | 解决方法 |
|---|---|
| 过渡不触发 | 确认条件块变化时元素被销毁/重建;使用 {#key} |
in:/out: 中途切换行为奇怪 | 这是单向行为的预期结果——只有 transition: 可反转 |
animate:flip 不工作 | 必须有 (key),且 animate: 必须放在带键 each 代码块的直接子元素上 |
flip 动画不流畅 | 确保 key 唯一且稳定 |
| 缓动函数不工作 | 确认已从 svelte/easing 正确导入 |
use: 参数变化不生效 | action 只调用一次;在 $effect 内部读取参数 |
| 编译器报错 | 查看上方的错误代码表 |
| 运行时警告 | 检查所有权链 |
示例
附有详细说明的实用用法模式:
- examples/README.md - 入口
- examples/store-patterns.md - 可写、可读、派生 store、自动订阅、跨组件共享
- examples/motion.md - 带缓动效果的补间和弹簧动画
- examples/transition.md - 内置过渡、自定义过渡、in/out 过渡
- examples/transitions-advanced.md - 交叉淡化、延迟过渡、过渡事件、自定义 css/tick
- examples/in-out-animate.md - in:/out: 分离过渡、animate:flip、自定义动画函数
- examples/use-action.md - 带类型标注、生命周期和自定义事件的 use: 指令
参考
完整的 API 文档:
- references/README.md - 入口
- references/store-reference.md - Store API 签名:writable、readable、derived、get、readonly
- references/motion-reference.md - Motion API:tweened、spring、缓动函数
- references/transition-reference.md - Transition API:fade、fly、slide、scale、自定义过渡
- references/transitions-complete.md - 所有内置过渡、事件、|global、自定义函数的完整参考
- references/in-out-reference.md - in: / out: 分离(单向)过渡
- references/animations-reference.md - animate: 指令、flip、自定义动画函数
- references/use-action-reference.md - use: action 类型标注、生命周期、Action<>、自定义事件
注意事项
svelte/transition的css和tick互斥 — 两者只能用一个in:/out:不可逆 — 中断时会放弃进行中的 intro,outro 会从 t=0 重新开始animate:必须位于 keyed each 的直接子元素上 — 嵌套 div 上的 animate: 不会运行flip需要稳定的 key — 使用唯一 ID,而非数组索引animate:不会响应添加/移除 — 只会在重新排序时触发- Store subscribe 会返回 unsubscribe 函数 — 组件卸载时会自动取消订阅
get(store)会创建临时订阅 — 频繁调用会影响性能elasticIn/elasticOut较慢 — 大量使用可能会影响性能use:action参数变化时不会重新调用 — 在 action 内部使用$effect响应变化