\n\n\n```\n\n2. 将处理函数包裹在内联箭头函数中,使其在事件触发时才被读取:\n\n```svelte\n\n```\n\n使用以下命令验证生产环境的结果:\n\n```shell\nvite build && vite preview\n```"}}]}]}

svelte

框架

sveltejs/svelte

将声明式组件编译为高效 JavaScript 的 Web 框架。

项目简介

Svelte 是一个前端框架,将声明式组件编译为高效 JavaScript,精准更新 DOM。它提供更简洁、更少代码的方式来构建响应式用户界面。开源且采用 MIT 许可。

README 预览

\n	\n		\n		\n	\n\n\n[](LICENSE.md) [](https://svelte.dev/chat)\n\n## What is Svelte?\n\nSvelte is a new way to build web applications. It's a compiler that takes your declarative components and converts them into efficient JavaScript that surgically updates the DOM.\n\nLearn more at the [Svelte website](https://svelte.dev), or stop by the [Discord chatroom](https://svelte.dev/chat).\n\n## Supporting Svelte\n\nSvelte is an MIT-licensed open source project with its ongoing development made possible entirely by fantastic volunteers. If you'd like to support their efforts, please consider:\n\n- [Becoming a backer on Open Collective](https://opencollective.com/svelte).\n\nFunds donated via Open Collective will be used for compensating expenses related to Svelte's development such as hosting costs. If sufficient donations are received, funds may also be used to support Svelte's development more directly.\n\n## Roadmap\n\nYou may view [our roadmap](https://svelte.dev/roadmap) if you'd like to see what we're currently working on.\n\n## Contributing\n\nPlease see the [Contributing Guide](CONTRIBUTING.md) and the [`svelte`](packages/svelte) package for information on contributing to Svelte.\n\n## Is svelte.dev down?\n\nProbably not, but it's possible. If you can't seem to access any `.dev` sites, check out [this SuperUser question and answer](https://superuser.com/q/1413402).\n\n## License\n\n[MIT](LICENSE.md)\n

常见问题 (5)

故障排除
如何修复在 Svelte 5 的 `$derived` 中,当稍后添加缺失的状态属性时,`in` 和 `Object.hasOwn` 不更新的问题?

这是 Svelte 5.57.2 中的一个响应式 bug。对于在 effect 之外创建的 $derived——例如在事件处理函数中实例化的类,或模块级 store——由于其父 effect 为 null,proxy 的 has trap 不会跟踪缺失的键。直接访问属性则可以正常工作,因为 get trap 总是会创建一个 source。

该问题已通过 PR #18944 修复,该 PR 将缺失键的跟踪条件从 active_effect !== null 改为 active_reaction !== null。请将 Svelte 5 升级到包含该修复的更新版本,最好是最新的 Svelte 5.x 版本。

作为临时解决方案,在使用 in 或 Object.hasOwn 之前,先在同一个 derived 中强制直接读取该属性:

has_x = $derived((this.state.x, 'x' in this.state));
owns_y = $derived((this.state.y, Object.hasOwn(this.state, 'y')));

直接读取会创建响应式属性 source,因此之后添加 x 或 y 会使该 derived 失效。

来源 Issue #18941
故障排除
为什么在 Svelte 5 中对 children snippet 使用 let:value 时会报 "value is not defined" 错误?

当子内容使用 {#snippet children()} 定义时,let: 指令不起作用;let:value 声明会被忽略,因此 value 为 undefined。请移除 let:value,改为通过 snippet 的参数接收该值:

<Child>
  {#snippet children({ value })}
    Value is: {value}
  {/snippet}
</Child>

此行为出现在 Svelte 5 中,包括 5.1.0 版本。

来源 Issue #13864
故障排除
如何修复在 $effect 或 onMount 中使用 untrack() 读取 $derived 时出现的 Svelte 5 内存泄漏问题?

这是由 Svelte 在非追踪读取(untracked read)期间连接后代派生值(derived)所导致的。该 derived 可能保持 CONNECTED 状态且 reactions === null,并仍然注册在诸如 page.data 之类的长生命周期 source 上,从而保留已卸载组件的上下文和 DOM。在 Svelte 5.57.0 中可以复现此问题,例如在 effect 内部使用 untrack(() => get(snapshot)) 这类模式,或在 onMount 中进行任何 derived 读取。

通过将 Svelte 升级到包含 derived 连接修复的 5.x 版本来解决:

npm install svelte@latest
# or
pnpm update svelte
# or
yarn upgrade svelte --latest

使用 npm ls svelte 验证已安装的版本。升级后,在 effect root 被销毁之后,复现示例最终的 source.reactions 应为 undefined,而不是仍然保留某个 reaction。

作为临时变通方案,避免仅在 untrack() 或 onMount 内部读取复杂的 $derived 链;应改为在这些位置读取原始状态,或重构代码,使该 derived 由正常的可追踪响应式上下文来读取。最终的修复是 Svelte 的补丁:只有当其活跃读取者本身已连接时,才连接该 derived。

来源 Issue #18827
故障排除
当 `<svelte:document bind:activeElement />` 移除被聚焦的元素时,如何修复 Svelte 的 `state_unsafe_mutation` 错误?

这是一个已知的 Svelte 5 bug(在 5.25.9 版本中报告)。当一个处于焦点状态的元素被 {#if} 块移除时,浏览器会在 Svelte 运行模板 effect 的同时触发 focusout,而 activeElement 绑定会尝试在该 effect 执行期间更新状态。

修复方法是将 Svelte 升级到包含以下修复的更新的 5.x 版本:"don't throw state_unsafe_mutation when the focused element is removed with bind:activeElement":

npm install svelte@latest

然后重启你的开发服务器/构建。

如果无法升级,可以使用临时解决方案:在移除元素之前先让其失去焦点(blur):

<button
  onclick={(event) => {
    event.currentTarget.blur();
    showButton = false;
  }}
>
  hello
</button>

或者,使用 requestAnimationFrame(() => (showButton = false)) 延迟移除操作。

来源 Issue #15742
故障排除
如何修复在生产构建中 Svelte 事件处理函数在顶层 await 之后变为 undefined 的问题?

这是一个 Svelte 5.57.1 编译器在启用 experimental.async: true 时出现的 bug。在生产环境中,处理函数在顶层 await 之后的代码为其赋值之前,就已经被传递给 $.delegated() 或 $.event(),因此监听器为 undefined。开发构建能正常工作,因为它们会延迟读取处理函数。

修复已在 PR #18933 中实现;待其发布后请升级 Svelte。在此之前,可使用以下变通方案之一:

1. 在第一个 await 之前创建处理函数:

<script>
	const make = (name) => () => console.log(name);
	const onclick = make('click');

	await Promise.resolve();
</script>

<button {onclick}>click</button>

2. 将处理函数包裹在内联箭头函数中,使其在事件触发时才被读取:

<button onclick={() => onclick()}>click</button>

使用以下命令验证生产环境的结果:

vite build && vite preview

来源 Issue #18932