Svelte 生命週期
tags: Svelte
category: Front-End
description: Svelte 生命週期
created_at: 2023/04/04 23:00:00
前言
Svelte
提供的生命週期相對來說比較少,不像是 Vue 3
有一大張圖,有興趣可以去看。
但也相對的比較簡單一些,主要就以下四個
onMount
onDestroy
beforeUpdate
afterUpdate
還有一個 tick()
函數
onMount & onDestroy
最簡單的生命週期,只會在頁面 mount
(掛上去DOM
) 時觸發
<script lang="ts">
import { onMount } from 'svelte';
onMount(() => {
console.log('mount page');
});
</script>
而對應到的就是 onDestroy
,就是當他從DOM
被拔掉(unmount
)時觸發
直接拿 Child.svelte
當範例
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
onMount(() => {
console.log('mount child');
});
onDestroy(() => {
console.log('destroy child');
});
</script>
<div>Child</div>
然後像這樣子使用他
<script lang="ts">
import Child from '../components/Child.svelte';
let num = 0;
</script>
<button on:click={() => num++}>num++</button>
{#if num % 2 == 0}
<Child />
{/if}
可以嘗試點按鈕,然後觀察 console
的變化。
beforeUpdate & afterUpdate
beforeUpdate
: 在DOM
更新之前觸發afterUpdate
: 在DOM
與資料同步後觸發
<script lang="ts">
import { afterUpdate, beforeUpdate } from 'svelte';
beforeUpdate(() => {
console.log('beforeUpdate');
});
afterUpdate(() => {
console.log('afterUpdate');
});
let num = 0;
</script>
<button on:click={() => num++}>num++</button>
{num}
並不是說畫面有更新才會觸發,也就是你把 {num}
拿掉,還是會觸發。
因為他只是個生命週期,他一直在循環在運作,只是用上面這樣解釋比較簡單。
其實有點像下面這樣(模擬而已):
updateVariable()
beforeUpdate()
updateDOM()
afterUpdate()
也就是說你在 beforeUpdate
拿的到新的變數,但會拿到舊的 DOM
。
在 afterUpdate
就都會拿到新的。
tick 函數
這個可能會比較需要想像一些,還記得在Svelte 響應式資料之$這一篇有提到一個問題
<script>
let count = 0;
$: doubleCount = count * 2;
const update = () => {
count += 1;
console.log(count, doubleCount);
};
</script>
<div>count: {count}</div>
<div>doubleCount: {doubleCount}</div>
<button on:click={update}>count++</button>
然後提到說 console.log
的值會錯,當時提到的解法是把 $
拉出去,如下
let count = 0;
$: doubleCount = count * 2;
const update = () => {
count += 1;
};
$: console.log(count, doubleCount);
還有一個解法,就是使用 tick()
,如下
<script>
import { tick } from 'svelte';
let count = 0;
$: doubleCount = count * 2;
const update = async () => {
count += 1;
await tick();
console.log(count, doubleCount);
};
</script>
<div>count: {count}</div>
<div>doubleCount: {doubleCount}</div>
<button on:click={update}>count++</button>
tick()
會回傳一個 Promise
,他會在你的 state
被更新到 DOM
完之後被 resolve
(如果有需要更新的話,不然他會立刻被 resolve
)
也可以看下面的範例更好理解
<script>
let count = 0;
const update = async () => {
count += 1;
count += 1;
count += 1;
};
$: console.log('count', count);
</script>
<button on:click={update}>count++</button>
這樣子當你按一下按鈕,count
會被增加 3
且只 console
出一次。
如果你希望可以三次都 console
出來,則可以在中間加入 tick()
import { tick } from 'svelte';
let count = 0;
const update = async () => {
count += 1;
await tick();
count += 1;
await tick();
count += 1;
};
最後更新時間: 2023年04月04日.