当您在 Svelte 5 中看到新的 $state 时,您可能会想做以下操作:
// sharedState.svelte.js export const searchState = $state(""); // This won't work!
<!-- App.svelte --> <script> import { searchState } from './sharedState.svelte.js' function handleClick(){ // This won't work! searchState = "bicycles"; } </script <button onclick={handleClick}>Search for bicycles</button>
这行不通 - 原因如下:
您正在遇到 Svelte 5 最复杂的部分。反应性如何工作以及编译器如何向您隐藏它。
当您导出数字或字符串等单个值时,Svelte 没有机制来保持反应性,因为 JavaScript 不提供跟踪该值的方法。
非常感谢 Mat Simon 用简单的语言向我解释了这一点?这是我学到的:
您不能直接使用字符串,但 $state 中的所有对象(和数组)都会获得 Svelte 5 自动代理的所有值。将字符串值包装到对象中是可行的:
// sharedState.svelte.js // ❌ export const searchState = $state(""); export const searchState = $state({ text : "" });
这变成了一个 Svelte 状态对象,带有 .text 的 getter 和 setter。您可以选择任何您想要的属性名称,以及多个属性。
当您导入此 $state 对象,并且然后写入 .text = 时,您正在使用 Svelte setter 来更新状态:
// App.svelte import { searchState } from './sharedState.svelte.js' function handleClick(){ // uses the automatically created setter searchState.text = "bicycles"; } <button onclick={handleClick}>Search for bicycles</button>
简单演示(REPL)):在组件之间共享 $state(简单)
Svelte 对于如何代理这些对象非常聪明。这就是为什么: myList.push('foo') 也适用于数组,因为 Svelte 也代理了 push 方法。
// data.svelte.js export const myList = $state([]);
当您使用对象(包括数组)时,它们本身也不是状态!理解这一点很重要。
如果你这样做,你就会失去反应能力!
import { searchState } from './sharedState.svelte.js'; searchState = {text: "Hello world!"}; // don't do this!
Svelte 无法为您处理此问题。始终通过 searchState.text = 'new value' 使用自动 Svelte getter/setter。
好的,对象和数组都很好,并且由 Svelte 自动处理 - 我们明白了。
但是
呢
标准 JavaScript 的日期、URL 和更多内置对象?如果您在 JavaScript 方面更有经验,您可能知道还有一些更高级的数据类型(标准内置对象):
Set 对象允许您存储任何类型的唯一值,无论是原始值还是对象引用。
Map 对象保存键值对并记住键的原始插入顺序。
如果你想将它们与reactive $state一起使用,你需要使用svelte/reactivity中相应的Svelte包装器
// sharedState.svelte.js export const searchState = $state(""); // This won't work!
之所以有一个单独的 SvelteSet 和 SvelteMap 类(而不是像处理对象和数组那样自动重写它)是因为他们想在某个地方画一条线,因为他们无法代理每个可以想象的对象。请参阅 https://github.com/sveltejs/svelte/issues/10263 了解技术细节。
有多种选项来定义状态对象,您还可以使用类来自定义方法:https://joyofcode.xyz/how-to-share-state-in-svelte-5#using-classes-for-反应状态
所以我们知道如何在组件内导入(和更新)状态,并且我们知道我们可以使用 $state 开箱即用的对象和数组:
<!-- App.svelte --> <script> import { searchState } from './sharedState.svelte.js' function handleClick(){ // This won't work! searchState = "bicycles"; } </script <button onclick={handleClick}>Search for bicycles</button>
我们甚至可以通过 $props 将 $state 对象作为属性的引用传递:
// sharedState.svelte.js // ❌ export const searchState = $state(""); export const searchState = $state({ text : "" });
// App.svelte import { searchState } from './sharedState.svelte.js' function handleClick(){ // uses the automatically created setter searchState.text = "bicycles"; } <button onclick={handleClick}>Search for bicycles</button>
但是当您位于组件内部时,您如何知道应用程序中某处的状态发生了变化?这就是 $衍生和 $衍生.by 的用途:
// data.svelte.js export const myList = $state([]);
简单演示(REPL)):在组件之间共享 $state(简单)
您可能已经知道,无需为文本输入编写处理函数。您可以使用bind:value={myStateObj}来自动更新状态:
import { searchState } from './sharedState.svelte.js'; searchState = {text: "Hello world!"}; // don't do this!
多个复选框输入也可以使用 Svelte 进行处理,通过 bind-group={stateObj} - 但关于如何与 $state 正确使用它仍然存在一个公开的讨论。
好消息:有多种方法可以做到这一点,请参见下文。
一种方法是使用 onchange 事件 >并更新处理函数中的状态。
简单演示 (REPL):使用复选框组组件和 v5 $state 和 $driven 进行搜索和过滤
完整的 SvelteKit 示例(WIP):https://github.com/mandrasch/austrian-web-dev-companies
我还开始了Reddit 讨论以获得更多反馈:
使用 Svelte v5 ($state) 搜索和过滤复选框的最简单方法是什么?
很高兴收到您的反馈 - 或在这里作为评论! ?
非常感谢马特·西蒙!
以上是Svelte 在组件之间共享状态(对于傻瓜来说)的详细内容。更多信息请关注PHP中文网其他相关文章!