onMount
每个组件都有一个生命周期,它从创建时开始,在销毁时结束。有一些函数允许您在生命周期的关键时刻运行代码。
最常用的是onMount,它在组件首次呈现给DOM之后运行。我们之前在渲染元素时遇到过它。
<script>
import { onMount } from 'svelte';
let photos = [];
onMount(async () => {
const res = await fetch(`https://jsonplaceholder.typicode.com/photos?_limit=20`);
photos = await res.json();
})
</script>
<style>
.photos {
width: 100%;
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-gap: 8px;
}
figure, img {
width: 100%;
margin: 0;
}
</style>
<h1>Photo album</h1>
<div class="photos">
{#each photos as photo}
<figure>
<img src={photo.thumbnailUrl} alt={photo.title}>
<figcaption>{photo.title}</figcaption>
</figure>
{:else}
<!-- this block renders when photos.length === 0 -->
<p>loading...</p>
{/each}
</div>
由于服务器端呈现(SSR)的原因,建议将获取放在onMount中,而不是放在
生命周期函数必须在组件初始化时被调用,这样回调函数就会绑定到组件实例上——而不是(比如说)在setTimeout中。
如果onMount回调函数返回一个函数,该函数将在组件销毁时被调用。
onDestroy
要在组件被销毁时运行代码,请使用onDestroy。
例如,我们可以在组件初始化时添加一个setInterval函数,并在它不再相关时清理它。这样做可以防止内存泄漏。
<script>
import { onDestroy } from 'svelte';
let seconds = 0;
const interval = setInterval(() => seconds += 1)
onDestroy(() => clearInterval(interval))
</script>
<p>
The page has been open for
{seconds} {seconds === 1 ? 'second' : 'seconds'}
</p>
虽然在组件初始化期间调用生命周期函数很重要,但从哪里调用它们并不重要。因此,如果我们愿意,我们可以将interval逻辑抽象为utils.js中的辅助函数…
import { onDestroy } from 'svelte';
export function onInterval(callback, milliseconds) {
const interval = setInterval(callback, milliseconds);
onDestroy(() => {
clearInterval(interval);
});
}
...然后将它导入到我们的组件中:
<script>
import { onInterval } from './utils.js';
let seconds = 0;
onInterval(() => seconds += 1, 1000);
</script>
beforeUpdate & afterUpdate
顾名思义,beforeUpdate 函数实现在DOM渲染完成前执行。afterUpdate函数则相反,它会运行在你的异步数据加载完成后。
总之,它们对于一些需要以状态驱动的地方很有用, 例如渲染标签的滚动位置。
let div;
let autoscroll;
beforeUpdate(() => {
autoscroll = div && (div.offsetHeight + div.scrollTop) > (div.scrollHeight - 20);
});
afterUpdate(() => {
if (autoscroll) div.scrollTo(0, div.scrollHeight);
});
请注意,beforeUpdate将在组件挂载之前首先运行,因此我们需要在读取div属性之前检查它是否存在。
Tick
tick函数不同于其他生命周期函数,因为您可以在任何时候调用它,而不仅仅是在组件第一次初始化的时候。它返回一个承诺,只要将任何挂起状态更改应用到DOM(如果没有挂起状态更改,则立即解决),该承诺就会立即解决。
当你在Svelte中更新组件状态时,它不会立即更新DOM。相反,它会等待到下一个微任务,以查看是否需要应用任何其他更改,包括在其他组件中。这样做可以避免不必要的工作,并允许浏览器更有效地进行批处理。
您可以在本例中看到这种行为。选择一个文本范围并按tab键。因为值改变了,当前选择被清除,光标跳转到末尾。我们可以通过导入tick来解决这个问题……
import { tick } from 'svelte';
... 然后在设置之前立即运行它。selectionStart这。handleKeydown末尾的selectionEnd:
await tick();
this.selectionStart = selectionStart;
this.selectionEnd = selectionEnd;