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条经验 获得超3个赞
有同样的疑问,然后我意识到“它将在块末尾添加和删除项目”可能意味着这里可能适用于 DOM,因此即使您在 JavaScript 中删除数组的第一项,Svelte 总是会删除最后一个DOM 节点。提供 key 后,DOM 和 JavaScript 都可以执行相同的操作。
添加回答
举报