SuperAPI AI 工具集

svelte-misc

前端与建站

查看项目

更新于 10-16 16:58

技能介绍

Svelte Misc Reference(Svelte 5)

本技能覆盖 Svelte 5 的 TypeScript 高级支持、自定义元素(Web Components)、浏览器兼容性矩阵、Svelte 4→5 迁移指南、官方最佳实践与常见问答。

使用时机

当用户需要 TypeScript 类型标注(泛型、包装组件、DOM 类型增强)、创建自定义 Web 组件并使用 $host() / $bindable / extend、查看浏览器兼容性矩阵与功能例外、从 Svelte 4 迁移到 Svelte 5,或遵循 Svelte 5 推荐的 $state / $derived / $effect 模式时使用本技能。

TypeScript 高级

Svelte 原生支持 TypeScript(Vite 项目无需配置)。用 <script lang="ts"> 启用类型注解;需要枚举 / 参数属性等运行时特性则需要预处理器。lang="ts" 默认只支持「类型只消失」的特性(注解、接口、泛型)。运行时代码特性(enum、private foo = 1 形式的参数属性)需配置 vitePreprocess({ script: true })。

类型 Props + 透传:用 interface Props 声明 requiredProperty、optionalProperty、snippetWithStringArgument、eventHandler,并用 [key: string]: unknown 配合 ...rest 透传其他属性。

泛型组件:<script> 的 generics 属性接受与函数泛型同样的语法,如 generics="Item extends { text: string }"。

包装组件(转发原生属性):使用 HTMLButtonAttributes 等类型,...rest 透传,children 用 {@render children?.()} 渲染。无专用接口的元素用 SvelteHTMLElements['div'] 形式。Component / ComponentProps<T> 用于约束动态组件与提取现有组件的 props。

类中 $state:count = $state() as number,无初值类型会扩为 undefined。

增强 svelte/elements:通过 .d.ts 声明模块,扩展 SvelteHTMLElements 或 HTMLAttributes<T>,末尾必须 export {}。

自定义元素(Web Components)

基础用法:<svelte:options customElement="my-element" />,导入即自动 customElements.define() 注册,消费者可读写 DOM 属性。必须显式声明 props,否则 Svelte 不知道要暴露哪些键。

customElement 选项字段:tag(标签名,设置后自动注册)、shadow('none' | 'open' | 'closed' | ShadowRootInit,默认 'open')、props.<name>.attribute(自定义属性名)、props.<name>.reflect(将 prop 值镜像到 HTML 属性,默认 false)、props.<name>.type('String' | 'Boolean' | 'Number' | 'Array' | 'Object',默认 'String')、extend(包装生成的类,可注入 lifecycle / ElementInternals)。

$host() Rune + 生命周期:可获取宿主元素。内部组件在 connectedCallback 之后的下一个 tick 创建;插入前设置的属性被缓冲并应用。Shadow DOM 更新批处理到下一个 tick;DOM 移动不会触发不必要的卸载。disconnectedCallback 后下一个 tick 销毁。

重要注意事项:样式封装而非「作用域」,全局 CSS 无法穿透 shadow root;CSS 内联为 JS 字符串而非单独 .css 文件;不适合 SSR;插槽内容积极渲染,<slot> 在 {#each} 里不会复制内容;let: 指令对自定义元素无效;Svelte context 不能跨自定义元素边界;不要命名 on* 属性。

浏览器兼容性

Svelte 5 目标是 Baseline 2020。最低版本:Chrome / Edge 87、Firefox 83、Safari 14、Opera 73、Opera (Android) 62、Samsung Internet 14.0、Android WebView 87;不支持 Internet Explorer。

功能例外:$state.snapshot 需 Chrome/Edge 98、Firefox 94、Safari 15.4;bind:devicePixelContentBoxSize 需 Firefox 93,Safari 不支持;flip(来自 svelte/animate)需 Firefox 126。

SSR 浏览器 API 保护:用 onMount 绑定 window 事件并返回清理函数;优先用 svelte:window / svelte:document,Svelte 自动处理 SSR 与卸载。

最佳实践

$state 只在需要时声明;只把会触发更新的值声明为 $state,大型只重赋值对象用 $state.raw 避免 Proxy 开销。纯计算用 $derived 而非 $effect,复杂逻辑用 $derived.by。$effect 是 escape hatch,优先 {@attach ...}、事件处理器、$inspect / $inspect.trace、createSubscriber。

Props 当作会变化,事件用属性语法。全局监听用 svelte:window / svelte:document。Snippets 替代 Slots,{#each ... (item.id)} 用稳定 key。style:-- 把 JS 变量透到 CSS 自定义属性。用 createContext 替代模块级共享状态。新代码避免 Legacy:on:click → onclick、export let → $props()、$: → $derived / $effect、<slot> → snippet、use:action → {@attach ...}。

Svelte 4 迁移指南

最低版本:Node 16+、SvelteKit 1.20.4+(如使用)、vite-plugin-svelte 2.4.1+、TypeScript 5+。

核心迁移对照:let x = 0 → let x = $state(0);$: x = a + b → let x = $derived(a + b);$: { ... } → $effect(() => { ... });export let prop → let { prop } = $props();<slot /> → {@render children()};createEventDispatcher → callback props;on:click={fn} → onclick={fn}。

自动迁移工具:npx svelte-migrate@latest svelte-5 my-project

重要行为变化:转换默认 local;默认插槽绑定不会进入具名插槽;预处理器顺序为 markup → script → style;createEventDispatcher 严格模式下检查类型;Action / ActionReturn 默认参数类型为 undefined;SvelteComponentTyped 已弃用;CJS 输出与 svelte/register 被移除;删除 svelte.JSX;打包器必须指定 browser 条件。

Svelte 5 概念摘要

Runes 系统:$state / $derived / $effect 替代隐式响应式;Snippets 替代 Slots;事件属性替代 on:;$effect 显式追踪依赖;$state 对对象/数组做深层 Proxy。

移除与替代:let 顶层隐式响应式 → $state;$: 语句 → $derived / $effect;export let / $$props / $$restProps → $props();createEventDispatcher → callback props / $bindable;Slots → Snippets;on:event → onevent;beforeUpdate / afterUpdate → $effect.pre / $effect。

新增:$state.eager、$effect.pre、$effect.tracking、$state.snapshot、hydratable、fork()、{#key} 过渡触发、svelte:boundary、createContext。

FAQ

Svelte 无虚拟 DOM,编译时生成精确 DOM 更新代码。Svelte 5 仍支持 Legacy Mode,可与 Svelte 4 渐进共存迁移。升级步骤:升级依赖、跑 npx svelte-migrate@latest svelte-5、逐步迁到 Runes Mode。SSR 与 TypeScript 都原生支持。自定义元素默认 shadow root 模式 'open',全局 CSS 不会穿透。

快速修复

Svelte 4 代码报错:确认组件未使用 $state;$: 不生效:升级到 Svelte 5;TypeScript 报错:确认 <script lang="ts"> 和 TypeScript 5+;迁移后打包变大:检查 tree-shaking 配置;属性以 on 开头被监听:重命名;自定义元素 SSR 没内容:预渲染不支持 shadow DOM;generic component 类型报错:检查 generics 字符串。

细节与陷阱

Svelte 5 自动进入 Runes Mode;可用 <svelte:options runes={false}> 强制 Legacy Mode。$bindable(default) 仅在父组件未传 prop 时作 fallback。bind:this 泛型组件实例类型为 Component<Props> | null。服务端 effect 不运行。

资料还包含示例与参考文档:动态组件、Debug 与 HTML、TypeScript 基础与高级、自定义元素 12 种模式、最佳实践 14 种模式、Svelte 3→4 迁移 10 种模式、浏览器支持 7 种模式等。