Skip to main content
Svelte 基础
介绍
响应式
属性
逻辑
事件
绑定
类和样式
Actions
过渡动画
Svelte 进阶
高级响应性
复用内容
Motion
高级绑定
高级过渡效果
Context API
特殊元素
<script module>
后续步骤
SvelteKit 基础
介绍
路由
加载数据
请求头和 Cookie
共享模块
表单
API 路由
$app/state
错误和重定向
SvelteKit 进阶
钩子函数
页面选项
链接选项
高级路由
高级加载
环境变量
结论

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

用实例来说明比解释更容易理解。在 Thing.svelte 中,name 是一个动态属性,而 emoji 是一个常量。

多次点击”Remove first thing”按钮,观察发生了什么:

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

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

解决这个问题的一种方法是将 emoji 设为 $derived 值。但与其删除最后一个组件并更新其他所有组件,不如直接删除第一个 <Thing> 组件更合理。

要实现这一点,我们需要为 each 块的每次迭代指定一个唯一的

App
{#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}