在我最近發布 Svelte 5 遷移的經驗和注意事項之後,我想重點介紹從 Svelte 4 遷移到 Svelte 5 時的一些技巧和心態的變化。
Svelte 4 使用「神奇的」$: 並讓和完成所有繁重的工作以使程式碼具有反應性。我們也接受了變數重新分配,例如
而不是更新/改變變數的方法,如推送等
我很驚訝能夠使用 Svelte 5 重新學習好的舊 JS 模式。
而且我也可能被 Svelte 4 中的 let 寵壞了,沒有考慮反應性,如果需要的話它會被包含在內。 但並非所有變數都必須是反應性的。非反應性變數也可以在反應性甚至“傳統變異代碼”中更新。反應式變數的真正需求是當我們在 UI 中使用它時(當這個變數在 html/頁面中呈現並且我們需要它稍後更新時)。
您可能會在 Svelte 5 中遇到錯誤,例如無法指派給衍生狀態,在其自己的範圍內所引用的狀態永遠不會更新。您的意思是在閉包內引用它嗎?或衍生_引用_selfn如果使用 Svelte 4 編碼風格,則派生值無法遞歸引用自身。
看一下這個 Svelte 4 風格的程式碼範例:
示範
我們有兩個反應變量,Svelte 4 會自動解決更新問題。我們只需要記住正確的方法是重新分配變數。
在 Svelte 5 中,我們應該思考如何達到相同的結果。我們使用的兩個變數還不夠,我們還需要一個,就是輔助變數。
首選方法是使用 $driven() 符文。
示範
如果您知道更簡單的方法,請告訴我。
還有一個 $effect() 符文方法可以達到相同的效果。它可能看起來更簡單,但我們應該盡可能避免效果(主要是 Svetlet 5 效果不在伺服器/SSR 上運行)。
示範
這是我嘗試將 Svelte 4 頁面直接遷移到 Svelte 5 的範例。我花了一段時間重新思考程式碼。此頁面用作帖子搜索,具有“加載更多”功能(如果用戶沒有 JS,則添加結果或分頁):
苗條4
從 '../components/Icon.svelte' 導入圖示; 從'$app/forms'導入{增強}; 從'svelte'導入{tick}; 出口許可證表格; 導出讓搜尋語言; 導出讓l; 讓結果= []; 讓以前的搜尋=''; 讓搜尋項; 讓我們跳過; $: if (!!form && form?.thereIsMore) { searchTerm = form.searchTerm; 跳過=數字(形式?.跳過)20; } $: if (!!form?.searchResultFromAction) { if (previousSearch == form.searchTerm && form.thereWasMore) { 結果= [...結果,...form.searchResultFromAction]; } 別的 { 結果= [...form.searchResultFromAction]; previousSearch = form.searchTerm; } } 非同步函數 intoView(el) { 等待刻度線(); if (el.attributes.index.nodeValue == 跳過 - 20 && 跳過!= 未定義) { el.scrollIntoView({ 行為: '平滑' }); } } 腳本> {#if 結果.length} <ol> {#每個結果作為項目,索引} <li use:intoview aria-posinset="{index}"> <!-- 沒有 javascript 的使用者已經計算了分頁中的結果順序,並且 css 禁用了標準 ol ul 編號 --> <!-- 使用 javascript 的使用者俱有標準的 ol ul 編號和載入更多功能 --> <noscript>{數字(索引)1 數字(形式?.skip)}。 無腳本> <a href="/act/%7BsearchingLang%7D/%7Bitem.id%7D/present/text">{item.title}</a> </noscript> </li> {/每個} </ol> {#if 形式? .thereIsMore} <!-- 可能我們不需要綁定該值,因為這是隱藏輸入 --> <!-- <input name="searchTerm" type="hidden" bind:value={searchTerm} /> --> 標籤> <button aria-label="載入更多搜尋結果的按鈕"> <p>苗條5<br> </p> <pre class="brush:php;toolbar:false"> 從 '../components/Icon.svelte' 導入圖示; 從'$app/forms'導入{增強}; 從'svelte'導入{tick}; let { form, searchLang, l } = $props(); 讓以前的搜尋=''; 設skip = $衍生.by(() => { if (!!form && form?.thereIsMore) { 返回 Number(form?.skip) 20; } }); 讓helperResultsArr = []; 讓結果= $衍生.by(() => { if (!!form?.searchResultFromAction) { if (previousSearch == form.searchTerm && form.thereWasMore) { helperResultsArr.push(...form.searchResultFromAction); 返回helperResultsArr; } 別的 { helperResultsArr = []; helperResultsArr.push(...form.searchResultFromAction); previousSearch = form.searchTerm; 返回helperResultsArr; } 否則返回[]; }); 非同步函數 intoView(el) { 等待刻度線(); if (el.attributes.index.nodeValue == 跳過 - 20 && 跳過!= 未定義) { el.scrollIntoView({ 行為: '平滑' }); } } 腳本> {#if 結果.length} <ol> {#每個結果作為項目,索引} <li use:intoview aria-posinset="{index}"> <!-- 沒有 javascript 的使用者已經計算了分頁中的結果順序,並且 css 禁用了標準 ol ul 編號 --> <!-- 使用 javascript 的使用者俱有標準的 ol ul 編號和載入更多功能 --> <noscript>{數字(索引)1 數字(形式?.skip)}。 無腳本> <a href="/act/%7BsearchingLang%7D/%7Bitem.id%7D/present/text">{item.title}</a> </noscript> </li> {/每個} </ol> {#if 形式? .thereIsMore} <input name="searchTerm" type="hidden" value="{form.searchTerm}">> 標籤> <button aria-label="載入更多搜尋結果的按鈕"> <p>現在就這些了。 </p> <p>PS:如果您願意以不同的方式進行遷移,請隨時告訴我。 </p> </button>
以上是Svelte 5 中的「助手」變數的詳細內容。更多資訊請關注PHP中文網其他相關文章!