Svelte基础
Svelte高阶
上下文API
特殊元素
接下来
SvelteKit基础
Shared modules
API routes
$app/state
Errors and redirects
Advanced SvelteKit
Page options
Link options
Advanced routing
Advanced loading
Environment variables
Conclusion
嗨,小主! 上个练习我们使用延迟转场演示了把元素从一个列表转移到另一个列表。
还需要让没有转场的元素看起来不那么生硬,我们可以使用animate指令.
首先在TodoList.svelte中从svelte/animate引入flip‘First, Last, Invert, Play首字母缩写’ 函数:
In the previous chapter, we used deferred transitions to create the illusion of motion as elements move from one todo list to the other. To complete the illusion, we also need to apply motion to the elements that aren’t transitioning. For this, we use the
animatedirective. First, import theflipfunction — flip stands for ‘First, Last, Invert, Play’ — fromsvelte/animateintoTodoList.svelte:
<script>
	import { flip } from 'svelte/animate';
	import { send, receive } from './transition.js';
	let { todos, remove } = $props();
</script><script lang="ts">
	import { flip } from 'svelte/animate';
	import { send, receive } from './transition.js';
	let { todos, remove } = $props();
</script>然后把它添加到<li>元素上:
Then add it to the
<li>elements:
<li
	class={{ done: todo.done }}
	in:receive={{ key: todo.id }}
	out:send={{ key: todo.id }}
	animate:flip
>如果觉得动画效果有点慢还可以调整下duration:
The movement is a little slow in this case, so we can add a
durationparameter:
<li
	class={{ done: todo.done }}
	in:receive={{ key: todo.id }}
	out:send={{ key: todo.id }}
	animate:flip={{ duration: 200 }}
>
duration也可以是个函数d => milliseconds, 其中d是元素经过的像素数 [!NOTE]durationcan also be ad => millisecondsfunction, wheredis the number of pixels the element has to travel
偷偷的告诉你,所有的转场和动画都是使用CSS实现的, 而不是使用JavaScript, 这样就不会阻塞主线程从而减少界面卡顿。
Note that all the transitions and animations are being applied with CSS, rather than JavaScript, meaning they won’t block (or be blocked by) the main thread.
<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>