首頁 >web前端 >js教程 >Svelte 在組件之間共用狀態(對於傻瓜來說)

Svelte 在組件之間共用狀態(對於傻瓜來說)

Mary-Kate Olsen
Mary-Kate Olsen原創
2025-01-03 17:18:43485瀏覽

Svelte Share state between components (for dummies)

當您在 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 與物件和陣列一起使用,而不是字串!

您不能直接使用字串,但 $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。

進階:使用 SvelteSet、SvelteMap、SvelteDate 等。

好的,物件和陣列都很好,並且由 Svelte 自動處理 - 我們明白了。

但是
呢 標準 JavaScript 的日期、URL 和更多內建物件?如果您在 JavaScript 方面更有經驗,您可能知道還有一些更高級的資料類型(標準內建物件):

  • Set 物件可讓您儲存任何類型的唯一值,無論是原始值還是物件參考。

  • Map 物件保存鍵值對並記住鍵的原始插入順序。

如果你想將它們與reactive $state一起使用,你需要使用svelte/reactivity中對應的Svelte包裝器

  • MediaQuery
  • SvelteDate
  • SvelteMap
  • SvelteSet
  • SvelteURL
  • SvelteURLSearchParams
// 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 和 $driven)

所以我們知道如何在元件內匯入(和更新)狀態,我們知道我們可以使用 $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 5 中共享狀態的不同方式 - 代碼之樂
  • 讓我們用 Svelte 5、Sveltekit 2、Tailwind、Upstash (2024) 建構一個過濾系統 - Lawal Adebola
  • Svelte 5 - 全球 $state(將商店轉換為 $state 符文)- Svelte Mastery

非常感謝馬特·西蒙!

以上是Svelte 在組件之間共用狀態(對於傻瓜來說)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn