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>

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号