搜尋
首頁web前端js教程學習新的 Svelte veactivity 系統

因此,Svelte v5,可能是現有最好的前端框架的最新版本已經發布,它與之前的版本有很大不同。主要差異在於其核心:如何實現變數的反應性。由於這些變化,Svelte 變得更容易,同時也變得更困難。

由於自v5@next.155 以來我一直在現實世界的微前端專案中與Svelte v5 密切合作,我決定撰寫本系列文章來傳遞我所獲得的知識來幫助您理解、接受並有可能將您的程式碼遷移到Svelte v5。

簡介:Svelte v4 反應性

Svelte v4 的反應系統簡直就是藝術品:Svelte 靜態分析元件中的程式碼,然後產生在常規 JavaScript 變數發生變化時強制更改 DOM 的程式碼。簡單、優雅且性能非常好。一個簡單的例子:

<script lang="ts">
    let clickCount = 0;

    function countClicks() {
        ++clickCount;
    }
</script>

<document on:click="{()"> countClicks()} />
<pre class="brush:php;toolbar:false">Clicks inside document: {clickCount}

這個簡單的元件為文件物件新增了一個「click」事件監聽器並計算點擊次數。只需上面的程式碼就可以即時顯示點擊次數。太棒了,對吧?

就像生活中的一切一樣,這並不完美。 Rich Harris(Svelte 的創作者)已經解釋了這些注意事項,我不會在本文中詳細介紹這些內容。我只提一個:程式碼重構。

程式碼重構是不可能的

更重要的警告之一是無法將該反應系統帶到組件之外。例如,我們無法建立一個可重複使用的模組來封裝範例中 countClicks 函數的實作。

由於反應性取決於靜態分析,因此將函數移走並放入模組中會將變數突變隱藏到靜態程式碼分析器中,然後反應性就會遺失。

Svelte v5 中的反應性:符文

符文一詞指的是“魔法符號”,Svelte 採用這個術語來命名以下功能外觀“魔法”術語:

  • $州

  • $道具

  • $可綁定

  • $衍生

  • $效果

Svelte v5 中的反應性是由這些符文的使用所控制。

值得注意的是,雖然它們看起來像 R 值,但它們產生的程式碼實際上是 L 值。換句話說,不要認為你可以在變數之間傳遞狀態。下面的 $state rune 部分對此進行了詳細介紹。

這種新反應系統的主要優點是:

  • 能夠在組件之外重構反應式程式碼

  • 細粒反應性

前者意味著我們可以在元件之外擁有響應式變數;後者意味著元件重新渲染在對狀態變化做出反應時更有針對性。

本文未介紹在組件外部擁有狀態的能力,但請關注本系列,因為將會有一篇關於此的文章。

另一方面,細粒度反應性意味著Svelte 現在可以知道狀態物件中的哪個屬性發生了變化,並且僅重新渲染(並重新運行效果並重新計算派生值)受該特定屬性影響的內容僅有的。在某些情況下,這是一個重大的效能改進。舉個簡單的例子:如果一個大型表格元件看到一個新行加入到其資料中,Svelte 將只渲染該新行。如果第三行中的單一儲存格值發生更改,則只有顯示該值的儲存格才會重新渲染。現在清楚了嗎?希望是這樣,但如果不是,請在評論部分打我。

$state符文

這個符文用來建立反應狀態。讓我們重寫上面的 Svelte v4 程式碼範例:

<script lang="ts">
    let clickCount = 0;

    function countClicks() {
        ++clickCount;
    }
</script>

<document on:click="{()"> countClicks()} />
<pre class="brush:php;toolbar:false">Clicks inside document: {clickCount}

為了達到與 Svelte v4 相同的結果,我們只需使用 $state(0) 而不是 0。

控制這個符文的主要規則是它只能用於初始化變數或類別字段,這與您剛才讀到的重要註釋有關:符文在語法上看起來像函數,但事實並非如此。編譯器用與函數功能(計算並傳回值)的想法不相容的程式碼取代符文。這表示以下不會建立第二個反應變數:

<script lang="ts">
    let clickCount = $state(0);

    function countClicks() {
        ++clickCount;
    }
</script>

<document onclick="{()"> countClicks()} />
<pre class="brush:php;toolbar:false">Clicks inside document: {clickCount}

clickCount 的反應性質不會透過使用賦值運算子轉移或複製到 secondaryClickCount。如果符文是函數,那麼上面的程式碼就可以工作,但它們不是

關於 $state 還有一件更重要的事情要提及:它使其值具有深度反應性。這意味著如果該值是屬性包含對象的對象,那麼所包含對象的屬性也是反應性的。這種模式遞歸地應用,因此整個物件圖最終都是反應性的。

$props 符文

元件屬性預計是反應性的,Svelte v5 使用 $props rune 實現了這一點。

<script lang="ts">
    let clickCount = $state(0);
    let secondClickCount = clickCount;

    function countClicks() {
        ++clickCount;
    }
</script>

因為使用 TypeScript 是專案的一切,所以我們先使用型別宣告元件屬性。可選屬性透過附加 ? 進行標記。正如它的名字一樣。

然後是符文的使用,這是一種解構語句。此範例展示如何指派預設值以及如何允許「其餘」屬性(即任何其他屬性)。此元件將屬性的「其餘」部分作為屬性(屬性)傳播(套用)到 span HTML 元素上。

你可以讓 props: Props = $props();定義屬性並且它可以工作,但是您無法指定各種屬性的預設值,因此我建議您始終按所示聲明屬性。順便說一下,如果不解構的話,我也不知道該如何聲明restProperties。

如果您注意的話,上面的程式碼會產生 TypeScript 錯誤。畢竟,Props 類型沒有提及任何「休息」屬性。我們如何輸入restProps?

一般來說,您可以執行以下操作來允許所有類型的操作。我想這取決於你的 TypeScript 技能。

以下開啟 Props 類型以允許任何 data-* 屬性:

<script lang="ts">
    let clickCount = 0;

    function countClicks() {
        ++clickCount;
    }
</script>

<document on:click="{()"> countClicks()} />
<pre class="brush:php;toolbar:false">Clicks inside document: {clickCount}

這個允許任何事:

<script lang="ts">
    let clickCount = $state(0);

    function countClicks() {
        ++clickCount;
    }
</script>

<document onclick="{()"> countClicks()} />
<pre class="brush:php;toolbar:false">Clicks inside document: {clickCount}

但通常情況下,需要允許接收 restProps 的 HTML 元素的屬性,在我們的範例中,這就是 span HTML 元素。

對於這個常見場景,Svelte v5 提供了應該覆蓋大部分 HTML 元素的類型:

<script lang="ts">
    let clickCount = $state(0);
    let secondClickCount = clickCount;

    function countClicks() {
        ++clickCount;
    }
</script>

使用後者將使 VS Code 等 GUI 為 span HTML 元素的可能的 props(屬性)提供準確的 Intellisense。不錯吧?

HTMLAttributes;介面用於屬性清單中沒有特殊性的 HTML 元素。然而,許多元素確實有。例如,不要執行 HTMLAttributes,而是從 'svelte/elements' 匯入 HTMLButtonAttributes 介面。

最後一個細節是預設值。其實沒什麼好說的,例子已經說明了一切:操作屬性的預設值是「sum」。如果在使用元件時未指定該屬性,則該屬性將採用該值。

如果所需的預設值未定義,則完全不要指定任何內容。

$可綁定符文

這是一個非常特殊的符文,只能在元件屬性中使用。它將屬性標記為可綁定。

如果您不知道或不記得,Svelte 允許屬性的 2 路綁定。 Vue 也有這個功能,而相較之下,React 沒有。

使用方法超簡單:

<script lang="ts">
    type Props = {
        data: number[];
        operation?: 'sum', 'avg';
    };

    let {
        data,
        operation = 'sum',
        ...restProps,
    }: Props = $props();

    function sum() {
        return data.reduce((p, c) => p + c);
    }

    function avg() {
        return sum() / data.length
    }
</script>

<span class="amount">{operation === 'sum' ? sum() : avg()}</span>

<style>
    .amount {
        font-family: monospace;
    }
</style>

始終將其值修改為可綁定的屬性,否則 Svelte 會發出控制台警告。此警告指出元件不應修改不屬於它們的狀態,如果有意這樣做,則應使用綁定。

如範例所示,可以透過 $bindable rune 指定屬性預設值。此範例將屬性的預設值設為 5。

但是預設值在這裡有意義嗎?嗯,是的。將屬性聲明為可綁定並不意味著它是必需的。

$衍生符文

每當我們需要使用 props 或其他反應狀態(可能隨時間變化)的值來計算值時,我們都會使用 $衍生符文。

將計算總和和平均值的範例元件帶回來,我們可以用這個符文重寫它:

<script lang="ts">
    let clickCount = 0;

    function countClicks() {
        ++clickCount;
    }
</script>

<document on:click="{()"> countClicks()} />
<pre class="brush:php;toolbar:false">Clicks inside document: {clickCount}

現在我們有一個名為 result 的新變量,它與其輸入一樣具有反應性,並且每次資料數組中的資料發生變化時都會自動重新計算。它本身是一個反應變量,因此使用它的模板(組件的 HTML 部分)也會更新。

$effect符文

這個符文允許我們指定在反應資料發生變化時執行的任意程式碼。為了讓這個符文發揮其魔力,它會追蹤在執行過程中讀取的反應資料。然後,每當庫存中的任何內容改變其值時,都會使用此反應資料庫存來重新觸發效果。

最常見的場景可能是根據更改的值重新觸發資料獲取操作:

<script lang="ts">
    let clickCount = $state(0);

    function countClicks() {
        ++clickCount;
    }
</script>

<document onclick="{()"> countClicks()} />
<pre class="brush:php;toolbar:false">Clicks inside document: {clickCount}

每當我們不希望 $衍生變數持有承諾時,非同步操作通常是內部效果的常態。但就我個人而言,由於在 Svelte 中使用 Promise 非常容易,所以我會簡單地使用 $driven 值。接下來顯示的變體使數據成為具有承諾的反應式計算值:

<script lang="ts">
    let clickCount = $state(0);
    let secondClickCount = clickCount;

    function countClicks() {
        ++clickCount;
    }
</script>

一般來說,如果您將 $state 和 $effect 結合起來,那麼使用 $driven 可能會更好。不過,這條規則也有例外,所以請將其視為經驗法則,而不是聖言。

如果資料取得不是 $effect 的一個很好的例子,那麼什麼才是呢?我們來看看這個:

<script lang="ts">
    type Props = {
        data: number[];
        operation?: 'sum', 'avg';
    };

    let {
        data,
        operation = 'sum',
        ...restProps,
    }: Props = $props();

    function sum() {
        return data.reduce((p, c) => p + c);
    }

    function avg() {
        return sum() / data.length
    }
</script>

<span class="amount">{operation === 'sum' ? sum() : avg()}</span>

<style>
    .amount {
        font-family: monospace;
    }
</style>

這是一個簡單的計時器元件,透過其狀態屬性進行控制。這裡使用 $effect 符文來強制計時器的操作。你能想像將其重構為 $衍生嗎?順便說一下,不要嘗試,因為 elapsed 是 prop,所以它不能同時是 $driven 和 prop。

結論

Svelte v5 配備了全新的反應性引擎,旨在實現更好的重新渲染效能和更好的程式碼重構。使用新的反應性系統既簡單又複雜:簡單是因為系統的設計很好地涵蓋了常見場景,而困難一點是因為與 v4 相比,程式碼變得更加複雜。

無論如何,新系統功能強大,能夠優雅而有效地滿足大多數場景,為所有可能的可能性提供符文,並且易於使用,儘管一開始有點奇怪。

下一步是什麼

本文僅介紹了符文的介紹部分,以及一些個人使用符文的經驗。還有更多主題可以幫助您(讀者朋友)更快掌握 Svelte 的新版本,即:

  • 深入了解 $effect 的工作原理

  • 高階符文($state.raw、$categories.by、$effect.pre 等)

  • 用反應狀態取代商店

  • 異常狀況

獎勵:性能圖表

看看這些基準測試結果:互動式結果 (krausest.github.io)

現在,框架清單令人震驚,因此您可以複製以下 JSON,然後使用「貼上」按鈕將其貼上到網頁中(請參閱螢幕截圖):

<script lang="ts">
    let clickCount = 0;

    function countClicks() {
        ++clickCount;
    }
</script>

<document on:click="{()"> countClicks()} />
<pre class="brush:php;toolbar:false">Clicks inside document: {clickCount}

Learning the new Svelte veactivity System

順便說一句,我認為簡單地聚焦視窗並透過鍵盤貼上也可以。

這將框架清單縮小到更流行的框架,或至少是我認為流行的框架。也許你比我更了解。

遺憾的是,Svelte v4 不再出現在圖表中,但正如您所看到的,在選定的框架中,前3 名是無可爭議的:Vanilla JS、Solid和Svelte。

另一方面,看到 React v19 表現如此糟糕令人難過。編譯器不是應該讓它變得更好嗎?看來最後的努力都是白費了。當然,它似乎優於 React v18,但僅此而已。我不確定為什麼 Meta 繼續在 React 上投資。大家有什麼想法嗎?

以上是學習新的 Svelte veactivity 系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python vs. JavaScript:選擇合適的工具Python vs. JavaScript:選擇合適的工具May 08, 2025 am 12:10 AM

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript:了解每個的優勢Python和JavaScript:了解每個的優勢May 06, 2025 am 12:15 AM

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架:為現代網絡開發提供動力JavaScript框架:為現代網絡開發提供動力May 02, 2025 am 12:04 AM

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

node.js流帶打字稿node.js流帶打字稿Apr 30, 2025 am 08:22 AM

Node.js擅長於高效I/O,這在很大程度上要歸功於流。 流媒體匯總處理數據,避免內存過載 - 大型文件,網絡任務和實時應用程序的理想。將流與打字稿的類型安全結合起來創建POWE

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用