🚲

Vue.jsのライフサイクルフックについて

2023/06/24に公開

なぜこの記事を書こうと思ったか

・今の現場の開発観点の一つに、ライフサイクルの観点を意識して実装することが挙げられたため。
・以前、自分自身もライフサイクル関連でハマった事があったので改めて理解を深めるため。

この記事を読んでわかること

onMounted、onUpdated、およびonUnmountedが呼ばれるタイミング

そもそもライフサイクルとは?

インスタンスの生成からコンポーネントが破棄されるまでの間に実行される関数のこと。
例えば、コンポーネントの作成、更新、破棄などのタイミングで実行される関数があります。

公式ドキュメントにて、より詳しく説明してあります。
https://ja.vuejs.org/guide/essentials/lifecycle.html#lifecycle-diagram

今回は、onMounted、onUpdated、およびonUnmountedに絞って解説します。

前提

・Vue.js v3^ (CompositionAPI)

結論

・onMounted
 コンポーネントがマウントされた後に呼び出されます。
・onUpdated
 そのコンポーネントがもつリアクティブなデータが更新され、
 コンポーネントのDOM更新後に呼び出されます。
※データの値が変わらない限り、onUpdatedは実行されないので注意!
・onUnmounted
 コンポーネントがアンマウントされた後に呼び出されます。

console.log()で確かめる

それでは先ほど説明したonMounted,onUpdated, onUnmountedがいつ呼ばれるのかについて
検証していきます。
今回は、以下のような画面を作成しました。
赤枠の部分が子コンポーネントになっており、親コンポーネントのボタンで表示、非表示を切り替えることができます。

サンプルコード

・親コンポーネント

Index.vue
<script setup>
import ChildComponent from '@/Components/ChildComponent.vue';
import { ref } from 'vue';

const isShow = ref(false)
// 子コンポーネントの表示切り替え
const toggle = () => {
    isShow.value = !isShow.value;
}
</script>
<template>
        <button type="button" @click="toggle">表示/非表示</button>
    <div v-if="isShow">
        <ChildComponent />
    </div>
</template>

・子コンポーネント

ChildComponent.vue
<script setup>
import { ref, onMounted, onUpdated, onUnmounted } from 'vue';
const text = ref('')

onMounted(() => {
    console.log('onMounted')
})

onUpdated(() => {
    console.log('onUpdated: ' + text.value)
})

onUnmounted(() => {
    console.log('onUnmounted')
})
</script>
<template>
    <label for="default-input">入力してください</label>
    <input type="text" id="default-input" v-model="text">
</template>

子コンポーネント内にonMounted、onUpdated、onUnmounted を登録し、どのタイミングで実行されるのか、コンソールを見て確かめたいと思います。

初期表示

コンソールには何も出力されていません。

onMounted発動!

ボタンを押すと、子コンポーネントが表示され、onMountedが実行されます。
ボタンを切り替えたことにより子コンポーネントのインスタンスが生成され、DOMツリーがレンダリングされたためです。

onUpdated発動!

文字を入力すると、onUpdatedが実行されます。
子コンポーネントが持っているデータ「text」が更新され、DOMツリーに反映されたためです。

onUnmounted発動!

再びボタンを押して子コンポーネントを非表示にすると、onUnmountedが実行されます。
子コンポーネントのインスタンスが削除されたためです。

補足

v-ifの部分をv-showにしたらどうなるでしょうか。

Index.vue
<template>
        <button type="button" @click="toggle">表示/非表示</button>
    <div v-show="isShow">
        <ChildComponent />
    </div>
</template>

結論から言うと、以下の挙動に変わります。
onMounted: 初期表示の段階で実行される
onUnmounted: 非表示にしても実行されない
理由は、v-showはcssの切り替えによって表示、非表示を切り替えているためです。
よって、画面がレンダリングされるタイミングで子コンポーネントのインスタンスが生成されます。
また、非表示にするボタンを押しても子コンポーネントのインスタンスが削除されることはありません。

■参考URL
https://ja.vuejs.org/api/composition-api-lifecycle.html

Discussion