跳至主要內容

上下文

大多數狀態是元件層級的狀態,其生命週期與元件相同。然而,也有區段範圍或應用程式範圍的狀態,也需要以某種方式處理。

最簡單的方法是建立全域狀態並直接匯入。

state.svelte
export const 
const myGlobalState: {
    user: {};
}
myGlobalState
=
function $state<{
    user: {};
}>(initial: {
    user: {};
}): {
    user: {};
} (+1 overload)
namespace $state

Declares reactive state.

Example:

let count = $state(0);

https://svelte.dev.org.tw/docs/svelte/$state

@paraminitial The initial value
$state
({
user: {}user: { /* ... */ } /* ... */ });
App
<script>
	import { myGlobalState } from './state.svelte';
	// ...
</script>

但這有一些缺點

  • 只有在您的全域狀態僅在客戶端使用時才能安全運作 - 例如,當您建置一個不在伺服器上渲染任何元件的單頁應用程式時。如果您的狀態最終在伺服器上管理和更新,則可能會在會話和/或使用者之間共享,導致錯誤
  • 它可能會給人一種錯誤的印象,認為某些狀態是全域的,但實際上它應該只在您的應用程式的某個部分中使用

為了解決這些缺點,Svelte 提供了一些 context 原始值來緩解這些問題。

設定與取得上下文

若要將任意物件與目前元件關聯,請使用 setContext

<script>
	import { setContext } from 'svelte';

	setContext('key', value);
</script>

然後可以使用 getContext 在元件的子元件(包括插槽內容)中使用此上下文。

<script>
	import { getContext } from 'svelte';

	const value = getContext('key');
</script>

setContextgetContext 解決了上述問題

  • 狀態不是全域的,而是限定於元件的作用域。這樣做可以在伺服器上安全地渲染您的元件,而不會洩漏狀態
  • 很明顯,狀態不是全域的,而是限定於特定元件樹狀結構的作用域,因此不能在應用程式的其他部分中使用

setContext / getContext 必須在元件初始化期間呼叫。

上下文本質上不是反應式的。如果您的上下文需要反應式的值,則可以將 $state 物件傳遞到上下文中,其屬性具有反應性。

父元件
<script>
	import { setContext } from 'svelte';

	let value = $state({ count: 0 });
	setContext('counter', value);
</script>

<button onclick={() => value.count++}>increment</button>
子元件
<script>
	import { getContext } from 'svelte';

	const value = getContext('counter');
</script>

<p>Count is {value.count}</p>

若要檢查給定的 key 是否已在父元件的上下文中設定,請使用 hasContext

<script>
	import { hasContext } from 'svelte';

	if (hasContext('key')) {
		// do something
	}
</script>

您也可以使用 getAllContexts 檢索屬於最接近的父元件的整個上下文映射。例如,如果您以程式設計方式建立元件並想要將現有上下文傳遞給它,這會很有用。

<script>
	import { getAllContexts } from 'svelte';

	const contexts = getAllContexts();
</script>

封裝上下文互動

上述方法對於如何使用它們非常沒有偏見。當您的應用程式規模擴大時,值得將設定和取得上下文封裝到函式中並正確輸入它們。

import { function getContext<T>(key: any): T

Retrieves the context that belongs to the closest parent component with the specified key. Must be called during component initialisation.

getContext
, function setContext<T>(key: any, context: T): T

Associates an arbitrary context object with the current component and the specified key and returns that object. The context is then available to children of the component (including slotted content) with getContext.

Like lifecycle functions, this must be called during component initialisation.

setContext
} from 'svelte';
let let userKey: symboluserKey =
var Symbol: SymbolConstructor
(description?: string | number) => symbol

Returns a new unique Symbol value.

@paramdescription Description of the new Symbol object.
Symbol
('user');
export function function setUserContext(user: User): voidsetUserContext(user: Useruser: type User = /*unresolved*/ anyUser) { setContext<User>(key: any, context: User): User

Associates an arbitrary context object with the current component and the specified key and returns that object. The context is then available to children of the component (including slotted content) with getContext.

Like lifecycle functions, this must be called during component initialisation.

setContext
(let userKey: symboluserKey, user: Useruser);
} export function function getUserContext(): UsergetUserContext(): type User = /*unresolved*/ anyUser { return getContext<User>(key: any): User

Retrieves the context that belongs to the closest parent component with the specified key. Must be called during component initialisation.

getContext
(let userKey: symboluserKey) as type User = /*unresolved*/ anyUser;
}

在 GitHub 上編輯此頁面