ライフサイクルフック
ライフサイクルフックについて学びましょう。
これは、コンポーネントの生成から破棄までの各段階で処理を実行するための、Vueの重要な機能です。
React経験者の方へ
ReactのuseEffectに相当する機能ですが、より明確に分かれています:
| React | Vue |
|---|---|
useEffect(() => {}, []) | onMounted(() => {}) |
useEffect(() => { return cleanup }, []) | onUnmounted(() => {}) |
Vueでは「何をするか」で関数が分かれているため、意図が明確になります。
主なライフサイクルフック
1. onBeforeMount
コンポーネントがDOMにマウントされる直前に実行されます。
2. onMounted
コンポーネントがDOMにマウントされた後に実行されます。
例:DOM要素へのアクセス
<script setup lang="ts">
const el = ref(null)
onMounted(() => {
console.log('マウントされました!')
console.log(el.value)
})
</script>
<template>
<div ref="el">
Hello
</div>
</template>
3. onBeforeUnmount
コンポーネントが破棄される直前に実行されます。
4. onUnmounted
コンポーネントが破棄された後に実行されます。
例:タイマーのクリーンアップ
<script setup lang="ts">
onMounted(() => {
const timer = setInterval(() => {
console.log('tick')
}, 1000)
})
onUnmounted(() => {
clearInterval(timer)
})
</script>
これが、Vueのライフサイクルフックの基本です。
Nuxt (SSR) での注意点
Nuxtでは、コードがサーバーとブラウザの両方で実行されます。 これを「SSR(サーバーサイドレンダリング)」と呼びます。
SSRについては、後ほど「ハイドレーション」のセクションで詳しく説明します。
重要なポイント
onMountedとonUnmountedはブラウザでのみ実行される- サーバーでは実行されない
悪い例
<script setup>
const width = window.innerWidth
</script>
良い例
<script setup>
const width = ref(0)
onMounted(() => {
width.value = window.innerWidth
})
</script>
チャレンジ
プレイグラウンドには、親コンポーネント(app.vue)と子コンポーネント(Child.vue)が用意されています。子コンポーネントのライフサイクルフックを実装して、マウント/アンマウントの回数をカウントしてみましょう。
親コンポーネント(app.vue)での作業
isVisibleという ref を作成し、初期値をtrueにしましょう。mountCountとunmountCountという ref を作成し、それぞれ初期値を0にしましょう。- ボタンをクリックすると
isVisibleの値を反転させるtoggleVisibility関数を作りましょう。 - 子コンポーネントから
mountedイベントを受け取ったらmountCountを1増やす関数を作りましょう。 - 子コンポーネントから
beforeUnmountイベントを受け取ったらunmountCountを1増やす関数を作りましょう。 v-if="isVisible"を使って、子コンポーネントの表示/非表示を切り替えられるようにしましょう。- template で
mountCountとunmountCountを表示しましょう。
子コンポーネント(Child.vue)での作業
emitを定義しましょう(mountedとbeforeUnmountの2つのイベント)。onMountedを追加して、親にmountedイベントを送りましょう。onBeforeUnmountを追加して、親にbeforeUnmountイベントを送りましょう。
ボタンをクリックして、子コンポーネントの表示/非表示を切り替えてみてください。マウント回数とアンマウント回数がカウントされることで、ライフサイクルフックの動作を確認できます!
もし手詰まりになったら、解決策を確認するためのボタンをクリックして、ヒントを得ることができます。