將訊號引入 Lit Labs
新的 Signals 套件將 TC39 Signals 提案與 Lit 整合
宣布 @lit-labs/signals:將 TC39 Signals 提案與 Lit 整合
我們很高興宣布推出我們最新的 Lit Labs 套件 @lit-labs/signals
,它將令人興奮的新 TC39 Signals 提案的 polyfill 直接與 Lit 整合。此套件提供了一種強大、反應式的方式來管理您的 Web 應用程式中的狀態,讓您可以使用共享的、可觀察的訊號,當它們的值變更時,會自動更新元件。
訊號正迅速成為 JavaScript 生態系統中的核心功能,而 TC39 提案有可能統一訊號以及我們如何在各種程式庫和框架中管理狀態和反應性。
雖然該提案仍處於早期階段,您今天就可以開始試用訊號和 @lit-labs/signals
,看看在通用反應式基礎上建構元件和應用程式是否適合您。
什麼是訊號?
簡單來說,訊號是可觀察的資料結構,其中保存值或計算結果。當訊號的值變更時,所有依賴它的元件或應用程式部分都會自動收到通知並更新。這在 UI 中特別有用,在 UI 中,多個元件可能需要共享狀態並對狀態變更做出反應。
基於標準的訊號的主要優點
- 共享的可觀察狀態:訊號非常適合管理在多個元件之間共享的狀態。如果一個元件更新訊號,所有其他使用它的元件也會自動更新。
- 精確更新:訊號可以實現精確的目標重新渲染,有可能透過僅處理其訊號支援值已變更的繫結,而跳過相同範本中的其他繫結來提高效能。
- 互通性:訊號的標準化意味著不同的程式庫和框架可以互通地使用訊號,從而減少對複雜轉接器的需求並提高相容性。
為什麼我們對 @lit-labs/signals
感到興奮
Lit 以其輕量級、高效能和宣告式的方式來建構 Web 元件而聞名。但 Lit 緊密地專注於幫助您建構可重複使用的、封裝的元件。Lit 不是一個框架,也不規定如何對您的資料建模或使其可觀察。
Lit 的反應性預設相對淺層。當元件自己的反應式屬性變更時,它們會自動更新,但當巢狀屬性變更時則不會。回應深層屬性變更需要手動更新請求,或是整合像是 Redux 或 MobX 之類的狀態管理系統。
訊號為我們提供了與這些狀態管理系統許多相同的深度可觀察性功能,但具有更小、更簡單的 API,並且有可能成為大量工具、元件和框架之間通用的標準。
訊號對 Lit 並非完全新事物。我們之前發布了 @lit-labs/preact-signals
套件,但我們對為特定的訊號程式庫建立 Lit 整合,以及可能為 Lit 開發人員可能想要使用的每個訊號程式庫建立 Lit 整合感到有些不滿意。
JavaScript 中的標準化訊號將讓我們僅建構一個整合(並最終直接在 Lit 的核心中新增訊號支援),並在與 Web 元件實現的互通性相同的精神下,啟用使用訊號的程式庫之間的互通性。
新的 @lit-labs/signals
套件讓您可以非常輕鬆地在您的 Lit 元件中使用新的訊號提案。
讓我們深入探討一些範例...
範例 1:共享計數器
這是一個使用 @lit-labs/signals
的共享計數器的簡單範例。若要在此元件中啟用基於訊號的反應性,我們只需在我們的自訂元素定義中使用 SignalWatcher
mixin;我們從中讀取的任何訊號都會被自動觀察,當它們的值變更時會觸發更新
import {LitElement, html} from 'lit';
import {customElement} from 'lit/decorators.js';
import {SignalWatcher, signal} from '@lit-labs/signals';
// This is a standard TC39 signal that uses the signals polyfill.
// The signal is shared across all component instances.
const count = signal(0);
@customElement('shared-counter')
export class SharedCounterComponent extends SignalWatcher(LitElement) {
render() {
// Just by using the signal in your template, your component will update
// when the signal changes.
return html`
<p>The count is ${count.get()}</p>
<button @click=${this.increment}>Increment</button>
`;
}
increment() {
count.set(count.get() + 1);
}
}
透過這種方法,任何數量的 <shared-counter>
元件都可以新增到 DOM,並且全部都會反映相同的計數器值,當訊號變更時會自動更新。
您也可以在 Lit 遊樂場中查看此範例。
範例 2:精確的 DOM 更新
使用 watch
指令,我們還可以實現精確更新,針對個別繫結而不是整個元件
import {LitElement, html} from 'lit';
import {customElement} from 'lit/decorators.js';
import {SignalWatcher, watch, signal} from '@lit-labs/signals';
const count = signal(0);
@customElement('pinpoint-counter')
export class PinpointCounter extends SignalWatcher(LitElement) {
render() {
return html`
<p>The count is ${watch(count)}</p>
<button @click=${this.increment}>Increment</button>
`;
}
increment() {
count.set(count.get() + 1);
}
}
在這裡,當訊號變更時,只會處理顯示計數的繫結,跳過不必要的工作並提高效能。
未來工作
這僅僅是我們探索 Lit 的訊號整合的開始。即將推出,我們將為 @lit-labs/signals
新增更多工具,以便增量渲染集合中的變更、輕鬆在元件中執行副作用,以及使用訊號進行反應式屬性。
最終,隨著擬議標準的進展以及我們在 Lit 中使用訊號的經驗增加,訊號可能會成為核心程式庫的一部分。
Lit 團隊正與 TC39 Signals 提案的擁護者密切合作,以確保訊號在 Lit、Web 元件和純 DOM 使用案例中都能良好運作。我們不能過度強調我們在訊號中看到的潛力,它能夠形成一個可互通的反應式基礎,可在程式庫和元件之間運作,而無需集中的框架。
試用並提供意見反應
我們渴望在您試用此新套件時收到社群的回饋。作為 Lit Labs 系列的一部分,@lit-labs/signals
仍處於實驗階段,可能會根據使用者回饋和 TC39 Signals 提案的進展進行重大變更。
若要開始,只需安裝套件
npm i @lit-labs/signals
我們很樂意聽取您的想法,所以請試用一下,並告訴我們它的運作方式。
- 初步文件可在 lit.dev/docs/data/signals/ 取得
- 您可以在 GitHub 意見反應討論 中分享意見反應
- 在 Lit monorepo issues 中報告問題
- 加入我們的 Discord 伺服器 來聊天!
我們很高興看到您將使用訊號建構什麼,以及它們將如何塑造 Web 應用程式中狀態管理的未來!
感謝!
-Lit 團隊