當您在 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中文網其他相關文章!