亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Svelte 對每個塊的鍵控的進一步解釋

Svelte 對每個塊的鍵控的進一步解釋

慕的地6264312 2022-10-13 10:42:43
我不明白教程中的這一部分:https ://svelte.dev/tutorial/keyed-each-blocks 。我可以看到things數組已正確更新,因此正確thing.color傳遞了預期。但是通過第一句“默認情況下,當你修改一個each塊的值時,它會在塊的末尾添加和刪除項目,并更新任何已更改的值?!?,似乎是說 Svelte 無論如何都會刪除單擊按鈕時的最后一個塊,則其余 4 個塊將面向切片things,即[{ id: 2, color: '#6a00a8' },  { id: 3, color: '#b12a90' },  { id: 4, color: '#e16462' },  { id: 5, color: '#fca636' }]并且由于initial被聲明為const,它不能再被更新,所以thing.id1--4 的顏色仍然存在。這是一個正確的理解嗎?each假設塊是可交換的,這是默認行為嗎?然后它說使用thing.id作為each塊的密鑰將解決問題,即{#each things as thing (thing.id)}. 我不明白這些鍵是如何在each塊中使用的,如果thing.id沒有提供默認鍵是什么。以及為什么默認密鑰(如果有一個,或者默認的無密鑰)在提供時thing.id不起作用。感謝您的澄清。
查看完整描述

4 回答

?
暮色呼如

TA貢獻1853條經驗 獲得超9個贊

我相信當您不提供密鑰時,它會使用類似項目的索引作為默認值。這可以通過使用來驗證

{#each things as thing, index (index)}
    <Thing current={thing.color}/>
    {/each}

這給出了與一開始不使用密鑰相同的行為。


讓我們稱為as<Thing>渲染的那個,依此類推。id: 1Thing1

沒有提供鑰匙

當我們從列表中刪除第一個項目時,它Thing1仍然保持不變,因為與之關聯的鍵(在本例中為索引)保持不變。之前發送到的道具Thing2現在正在發送到Thing1。這發生在整個鏈條上。但是現在少了一個元素,Thing5從 DOM 中刪除。

刪除第一項時,Thing與鍵“0”( )關聯的組件實例不會被破壞。Thing1發生這種情況是因為鍵保持不變(新數組在索引 0 處也有一個項目)。只有被發送到的道具Thing1發生了變化,使initial變量與原始項目的顏色保持一致id: 1

提供 (thing.id) 密鑰

id: 1刪除帶有的事物時,不存在任何Thing映射到“1”的實例。因此,Thing1從 DOM 中刪除。


另一種理解方式是,當你給出一個鍵時,你實際上是在告訴 Svelte 將每個渲染塊映射到那個鍵。當該鍵不再存在時,擺脫該塊并將其從 DOM 中刪除。但是如果密鑰保持不變并且道具發生變化,請更新道具而不是重新創建塊。

當您不指定鍵時,它使用列表的索引作為鍵。因此,如果您從列表中刪除項目,它不會重新創建或重新排序塊,它只會更新道具。


查看完整回答
反對 回復 2022-10-13
?
慕虎7371278

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}

我發現這在教程中也缺乏適當的解釋。但是,我認為文檔更清晰——可以為每個函數提供一個唯一鍵,以便唯一標識每次迭代。因此,當從提供給每個函數的數據中刪除特定元素時,可以識別和刪除正確的迭代。


查看完整回答
反對 回復 2022-10-13
?
jeck貓

TA貢獻1909條經驗 獲得超7個贊

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



查看完整回答
反對 回復 2022-10-13
?
守著一只汪

TA貢獻1872條經驗 獲得超4個贊

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



查看完整回答
反對 回復 2022-10-13
  • 4 回答
  • 0 關注
  • 170 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號