跳至主要内容

默认情况下,当你修改 each 块的值时,它会在块的末尾添加和删除 DOM 节点,并更新任何已更改的值。这可能不是你想要的。

用示例说明比解释更容易。在 Thing.svelte 中,name 是一个动态 prop,但 emoji 是一个常量。

点击“移除第一个事物”按钮几次,注意会发生什么。

  1. 它删除了最后一个组件。
  2. 然后它更新了剩余 DOM 节点中的 name 值,但没有更新 emoji。

如果你来自 React,这可能看起来很奇怪,因为你习惯于在状态更改时整个组件重新渲染。Svelte 的工作方式不同:组件“运行”一次,随后的更新是“细粒度的”。这使得事情变得更快,并让你有更多的控制权。

一种解决方法是使 emoji 成为 $derived 值。但删除第一个 <Thing> 组件本身比删除最后一个组件并更新所有其他组件更有意义。

为此,我们为 each 块的每次迭代指定一个唯一的

应用
{#each things as thing (thing.id)}
	<Thing name={thing.name}/>
{/each}

你可以使用任何对象作为键,因为 Svelte 在内部使用 Map——换句话说,你可以使用 (thing) 而不是 (thing.id)。然而,使用字符串或数字通常更安全,因为它意味着身份在没有引用相等的情况下仍然存在,例如当使用来自 API 服务器的新数据进行更新时。

在 GitHub 上编辑此页面

上一页 下一页
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
	import Thing from './Thing.svelte';
 
	let things = $state([
		{ id: 1, name: 'apple' },
		{ id: 2, name: 'banana' },
		{ id: 3, name: 'carrot' },
		{ id: 4, name: 'doughnut' },
		{ id: 5, name: 'egg' }
	]);
</script>
 
<button onclick={() => things.shift()}>
	Remove first thing
</button>
 
{#each things as thing}
	<Thing name={thing.name} />
{/each}