4 回答

TA貢獻1853條經驗 獲得超9個贊
我相信當您不提供密鑰時,它會使用類似項目的索引作為默認值。這可以通過使用來驗證
{#each things as thing, index (index)} <Thing current={thing.color}/> {/each}
這給出了與一開始不使用密鑰相同的行為。
讓我們稱為as<Thing>
渲染的那個,依此類推。id: 1
Thing1
沒有提供鑰匙
當我們從列表中刪除第一個項目時,它Thing1
仍然保持不變,因為與之關聯的鍵(在本例中為索引)保持不變。之前發送到的道具Thing2
現在正在發送到Thing1
。這發生在整個鏈條上。但是現在少了一個元素,Thing5
從 DOM 中刪除。
刪除第一項時,Thing
與鍵“0”( )關聯的組件實例不會被破壞。Thing1
發生這種情況是因為鍵保持不變(新數組在索引 0 處也有一個項目)。只有被發送到的道具Thing1
發生了變化,使initial
變量與原始項目的顏色保持一致id: 1
。
提供 (thing.id) 密鑰
當id: 1
刪除帶有的事物時,不存在任何Thing
映射到“1”的實例。因此,Thing1
從 DOM 中刪除。
另一種理解方式是,當你給出一個鍵時,你實際上是在告訴 Svelte 將每個渲染塊映射到那個鍵。當該鍵不再存在時,擺脫該塊并將其從 DOM 中刪除。但是如果密鑰保持不變并且道具發生變化,請更新道具而不是重新創建塊。
當您不指定鍵時,它使用列表的索引作為鍵。因此,如果您從列表中刪除項目,它不會重新創建或重新排序塊,它只會更新道具。

TA貢獻1802條經驗 獲得超4個贊
API 文檔是這樣解釋的:
如果提供了一個鍵表達式——它必須唯一地標識每個列表項——Svelte 將在數據更改時使用它來區分列表,而不是在最后添加或刪除項目。鍵可以是任何對象,但建議使用字符串和數字,因為它們允許標識在對象本身更改時保持不變。
{#each items as item (item.id)}
<li>{item.name} x {item.qty}</li>
{/each}
<!-- or with additional index value -->
{#each items as item, i (item.id)}
<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}
我發現這在教程中也缺乏適當的解釋。但是,我認為文檔更清晰——可以為每個函數提供一個唯一鍵,以便唯一標識每次迭代。因此,當從提供給每個函數的數據中刪除特定元素時,可以識別和刪除正確的迭代。

TA貢獻1909條經驗 獲得超7個贊
我也在這個例子中苦苦掙扎,為什么圖標沒有改變。我注意到初始化 ( const emoji = emojis[name]
) 之后在組件中計算的值保持不變,但是如果我們使用響應式聲明:$: emoji = emojis[name];
值將被重新計算,并且此示例可以正常工作。

TA貢獻1872條經驗 獲得超4個贊
有同樣的疑問,然后我意識到“它將在塊末尾添加和刪除項目”可能意味著這里可能適用于 DOM,因此即使您在 JavaScript 中刪除數組的第一項,Svelte 總是會刪除最后一個DOM 節點。提供 key 后,DOM 和 JavaScript 都可以執行相同的操作。
添加回答
舉報