Svelte 迷途求索(三) —— 生命周期
每个组件都有从创建到销毁的过程,这个过程被称为生命周期
生命周期可以解决一些业务上的需求,比如组件加载时请求数据、组件销毁时清除定时器
Svelte 提供了五个生命周期函数:组件加载 onMount、更新前 beforeUpdate、更新后 afterUpdate、组件销毁 onDestroy、tick
下面将介绍这些生命周期函数的用法,以及它们各自的触发时机
一、组件加载
Svelte 提供的 onMount 函数会在组件加载完成后执行,类似于原生的 window.onload
一些需要在页面加载时请求的接口,可以通过 onMount 调用
<script>
import { onMount } from 'svelte';
onMount(async () => {
console.log('组件加载完毕');
const res = await fetch('/api');
// do something
});
</script>
对于兄弟组件,onMount 会根据组件调用的顺序,从上往下执行
而对于父子组件,当子组件的 onMount 执行完毕之后,才会执行父组件的 onMount,也就是从内到外
此外,如果 onMount 返回了一个函数,这个函数就会在组件销毁时执行
onMount(async () => {
console.log('组件加载完毕');
return () => {
console.log('这段代码会在组件销毁时执行');
}
});
二、组件更新
组件内的状态更新时,会执行 beforeUpdate,更新完毕之后会执行 afterUpdate
<script>
import { beforeUpdate, afterUpdate } from 'svelte';
beforeUpdate(() => {
console.log('开始更新...');
});
afterUpdate(() => {
console.log('更新完毕');
});
</script>
对于兄弟组件,beforeUpdate 和 afterUpdate 依然是按照组件调用的顺序,从上往下执行
而对于父子组件,会先执行父组件的 beforeUpdate,然后执行子组件的 beforeUpdate
当子组件的 beforeUpdate 执行完毕之后,再执行父组件的 afterUpdate,最后执行子组件的 afterUpdate
还有一点需要注意,如果组件中同时存在 beforeUpdate 与 onMount,首次 beforeUpdate 回调会在 onMount 之前
而父组件的 onMount 会在子组件的执行完毕后才执行,所以子组件 beforeUpdate/afterUpdate 的首次调用,会在父组件 onMount 之前
三、组件销毁
Svelte 提供的 onDestroy 函数会在组件加载完成后执行
<script>
import { onDestroy } from 'svelte';
onDestroy(() => {
console.log('组件即将被销毁');
});
</script>
兄弟组件之间的 onDestroy 依然是根据调用顺序从上往下
而父子组件则是从外到内,先执行父组件的 onDestroy,再执行子组件的 onDestroy
上面介绍 onMount 的时候有提到,onMount 返回的函数会在组件销毁的时候执行,这个函数会在 onDestroy 之后执行
所以一个完整的生命周期是这样的:
// Child A 是 Parent 的子组件,Child A-1 是 Child A 的子组件
加载:
更新:
销毁:
四、Tick
开发过程中可能会遇到这种问题:组件中的某个状态更新了,但 DOM 没有更新
这时就可以使用 tick 函数,它会返回一个 Promise,当组件的状态更新之后,会触发这个 Promise 的 resolves
其实 tick 就像是 Vue 中的 nextTick,或者简单粗暴的理解为 setTimeout
简单的说,我们可以借助 tick 来执行一段异步代码,从而解决数据更新但 DOM 不更新的问题
<script>
import { beforeUpdate, tick } from 'svelte';
beforeUpdate(async () => {
await tick();
console.log('这段代码会在组件状态更新后执行');
});
</script>