Skip to main content
Svelte基础
介绍
响应
属性Props
逻辑表达式
事件
绑定
Classes和样式
动作Actions
转场
Svelte高阶
响应式进阶
内容复用
动画
高级绑定
高级转场
上下文API
特殊元素
脚本模块
接下来
SvelteKit基础
介绍
路由
加载数据
Headers和cookies
Shared modules
Forms
API routes
$app/state
Errors and redirects
Advanced SvelteKit
Hooks
Page options
Link options
Advanced routing
Advanced loading
Environment variables
Conclusion

Svelte转场引擎还有个特别强大的功能 —— 延迟 转场,可以在多个元素之间协调转场效果。 以这个成对的待办事项列表为例,在其中切换一个待办事项会将其发送到另一个列表。在现实世界中,物体不会突然消失并在另一个地方重新出现,而是会经过一系列中间位置。使用运动效果可以大大帮助用户理解你的应用程序中发生了什么。 我们可以使用 crossfade 函数来实现这种效果,如 transition.js 中所示,该函数创建了一对名为 sendreceive 的转场。当一个元素被“发送”时,它会寻找一个正在被“接收”的对应元素,并生成一个转场效果,将该元素变换到其对应元素的位置并淡出。当一个元素被“接收”时,会发生相反的过程。如果没有对应的元素,则使用 fallback。 打开 TodoList.svelte。首先,从 transition.js 中导入 sendreceive 转场:

A particularly powerful feature of Svelte’s transition engine is the ability to defer transitions, so that they can be coordinated between multiple elements. Take this pair of todo lists, in which toggling a todo sends it to the opposite list. In the real world, objects don’t behave like that — instead of disappearing and reappearing in another place, they move through a series of intermediate positions. Using motion can go a long way towards helping users understand what’s happening in your app. We can achieve this effect using the crossfade function, as seen in transition.js, which creates a pair of transitions called send and receive. When an element is ‘sent’, it looks for a corresponding element being ‘received’, and generates a transition that transforms the element to its counterpart’s position and fades it out. When an element is ‘received’, the reverse happens. If there is no counterpart, the fallback transition is used. Open TodoList.svelte. First, import the send and receive transitions from transition.js:

TodoList
<script>
	import { send, receive } from './transition.js';

	let { todos, remove } = $props();
</script>
<script lang="ts">
	import { send, receive } from './transition.js';

	let { todos, remove } = $props();
</script>

然后,将它们添加到 <li> 元素并使用todo.id 作为键来匹配元素:

Then, add them to the <li> element, using the todo.id property as a key to match the elements:

TodoList
<li
	class={{ done: todo.done }}
	in:receive={{ key: todo.id }}
	out:send={{ key: todo.id }}
>

现在,当你切换项目时,它们会平滑地移动到新的位置。没有添加转场效果的元素看起来还有些生硬——我们将在下一个练习中修复这个问题。 Now, when you toggle items, they move smoothly to their new location. The non-transitioning items still jump around awkwardly — we can fix that in the next exercise.

Edit this page on GitHub

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<script>
	import TodoList from './TodoList.svelte';
 
	const todos = $state([
		{ id: 1, done: false, description: 'write some docs' },
		{ id: 2, done: false, description: 'start writing blog post' },
		{ id: 3, done: true, description: 'buy some milk' },
		{ id: 4, done: false, description: 'mow the lawn' },
		{ id: 5, done: false, description: 'feed the turtle' },
		{ id: 6, done: false, description: 'fix some bugs' }
	]);
 
	let uid = todos.length + 1;
 
	function remove(todo) {
		const index = todos.indexOf(todo);
		todos.splice(index, 1);
	}
</script>
 
<div class="board">
	<input
		placeholder="what needs to be done?"
		onkeydown={(e) => {
			if (e.key !== 'Enter') return;
 
			todos.push({
				id: uid++,
				done: false,
				description: e.currentTarget.value
			});
 
			e.currentTarget.value = '';
		}}
	/>
 
	<div class="todo">
		<h2>todo</h2>
		<TodoList todos={todos.filter((t) => !t.done)} {remove} />
	</div>
 
	<div class="done">
		<h2>done</h2>
		<TodoList todos={todos.filter((t) => t.done)} {remove} />
	</div>
</div>
 
<style>
	.board {
		display: grid;
		grid-template-columns: 1fr 1fr;
		grid-column-gap: 1em;
		max-width: 36em;
		margin: 0 auto;
	}
 
	.board > input {
		font-size: 1.4em;
		grid-column: 1/3;
		padding: 0.5em;
		margin: 0 0 1rem 0;
	}
 
	h2 {
		font-size: 2em;
		font-weight: 200;
	}
</style>