Дальнейшее объяснение того, как Svelte использует каждый блок - PullRequest
1 голос
/ 21 июня 2020

Я не понимаю этот раздел в руководстве: 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.id 1-4 остаются.

Это правильное понимание? Это поведение по умолчанию предполагает, что блоки each можно заменять?

Затем говорится, что использование thing.id в качестве ключа для блоков each решит проблему, а именно {#each things as thing (thing.id)}. Я не понимаю, как ключи используются в блоках each и какой ключ был по умолчанию, если thing.id не указан. И почему ключ по умолчанию (если он есть, или без ключа по умолчанию) не работает, а при предоставлении thing.id работает.

Спасибо за пояснение.

1 Ответ

2 голосов
/ 21 июня 2020

Я считаю, что он использует что-то вроде индекса элемента по умолчанию, когда вы не предоставляете ключ. Это можно проверить, используя

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

, что дает такое же поведение, как если бы вы вообще не использовали ключ.

Давайте назовем <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. Но если ключ остается прежним, а реквизиты меняются, обновите реквизиты вместо воссоздания блока.

Если вы не указываете ключ, он использует индекс списка в качестве ключа. Таким образом, если вы удалите элементы из списка, блок не будет воссоздан или переупорядочен, а просто обновятся реквизиты.

...