Talk is cheap. Show me your code

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>

 

posted @ 2022-02-07 12:52  Wise.Wrong  阅读(469)  评论(0编辑  收藏  举报