ライフサイクルフックとは
Vueコンポーネントには、以下のようなライフサイクルが存在します。
- Vueインスタンスが作成される:create
- VueインスタンスがDOM要素にマウント(
<template>内がHTMLに変換)される:mount - リアクティブなデータが変更される:update
- Vueインスタンスが破棄される:destroy / unmount
これらそれぞれのタイミングの前後で自動的に呼び出される処理を定義することができるメソッドが、Vueでは用意されています。これを「ライフサイクルフック」と呼びます。
beforeCreate
dataなどの初期化前、何よりも最初に実行される処理を記載するフックです。
この時点ではdataやmethodsなどの初期化は完了していないので、リアクティブなデータやイベントリスナーなどを利用(dataの値を変更したり、参照したり)できません。
その為、dataが関わらない(リアクティブ性が必要ない)処理を一番最初に行いたい際に有効です。
認証チェックのAPIなどをここで実行するのはありかなあとは思いますが、あまりbeforeCreateを使用しているケースを見たことがありません。
Vue2
<script>
export default {
data () {
return {
name: "",
};
},
beforeCreate() {
console.log("Before create");
},
};
</script>
Vue3
Vue2でbeforeCreate、createdの中で表現していた処理は、setup内にそのまま処理を記載するような形になりました。
最初に実行される処理としてわかりやすいように、初期表示処理を即時関数として定義することをオススメします。
<script setup lang="ts">
import { ref } from "vue";
(() => {
console.log("Before create");
})();
const name = ref<string>("");
</script>
created
dataやmethodsの初期化は完了しているが、DOM(<template>の中)は生成されていない状態で実行されるフックです。
beforeCreated内ではdataやmethodsの初期化が完了していなかった為アクセスすることができませんが、この時点からアクセスすることが可能です。
初期遷移時、DOMを生成する前に何かAPIを実行して、dataの初期値として設定したりする場合はcreatedで実行するのが良いとされています。
Vue2
<script>
export default {
data() {
name: ""
},
created() {
this.name = "Whopper";
},
};
</script>
Vue3
beforeCreate同様、Vue2までcreatedの中で表現していた処理はsetup内にそのまま記載します。
<script setup lang="ts">
import { ref } from "vue";
const name = ref<string>("");
(() => {
name.value = "Whopper";
})();
</script>
beforeMount
VueインスタンスがDOMにマウントされる前に実行されるフックです。
「VueインスタンスがDOMにマウントされる」というのは、「Vueの
<template>内がコンパイルされ、実際のHTMLに変換されること」を言います。
created同様、dataやmethodsの初期化は完了しているが、DOMにマウントされていない状態の為、違いがよく分からなくなりそうですが、実行されるタイミングという観点で言うと、だいたい同じものという認識で大丈夫な気もします。
Vue2
<script>
export default {
beforeMount() {
console.log("before mount");
},
};
</script>
Vue3
<script setup lang="ts">
import { onBeforeMount } from "vue";
onBeforeMount(() => {
console.log("before mount");
});
</script>
mounted
インスタンスがDOMにマウントされた後に実行されるフックです。
DOM要素(<template>内)へのアクセスを伴う処理、外部ライブラリの初期化やイベントリスナーの設定などをする際に有効です。
使用している子コンポーネントが全てマウントされている & 現コンポーネントがマウントされたら初めて「マウントされた」ということになります。その為、子コンポーネント内のmountedは親コンポーネントのmountedより先に実行されるということに注意です。
Vue2
<script>
export default {
mounted() {
console.log("mounted");
},
};
</script>
Vue3
<script setup lang="ts">
import { onMounted } from "vue";
onMounted(() => {
console.log("mounted");
});
</script>
余談: createdとmountedについて
よく違いが曖昧になりがちなcreatedとmountedですが、
「DOMへのマウント(<template>内HTMLへの変換)が完了しているかどうか」という違いの他にも、「mountedはSSR(サーバーサイドレンダリング)有効時には呼び出されない」という点を覚えておくと尚良いです!
これは、mountedはあくまでブラウザ上でVueインスタンスがDOMにマウントされたというイベントに対するフックであることが理由です。
SSRではVue.jsのコードは事前にサーバー上で実行され、レンダリングされたHTML(既に<template>内が変換されたもの)がブラウザに渡される為、「ブラウザ上でVueインスタンスがDOMにマウントされる」というイベントは発生しない為、mountedは実行されないのです。(beforeMountも同様です)
SSR有効時には、基本的にはcreatedを使用することが推奨されています。
beforeUpdate
dataの値が更新され、DOMに適用される前に実行されるフックです。
この時点ではDOMには反映されていないので、データのバリデーションや変更のキャンセルなど、更新前の操作を行うのに適しています。
たとえばフォームに入力された文字数が制限を超えた場合、新しいデータがDOMに反映される前に、文字数を制限内に調整するなどの場合はここに処理を書くのが相応しいです。
Vue2
<script>
export default {
beforeUpdate() {
console.log("before update");
},
};
</script>
Vue3
<script setup lang="ts">
import { onBeforeUpdate } from "vue";
onBeforeUpdate(() => {
console.log("before update");
});
</script>
updated
dataの値が更新され、DOMに適用された後に実行されるフックです。
DOMが更新された後の後処理や、更新されたDOM要素にアクセスして特定の処理を行うことができます。
たとえば、なんらかのリストにデータを追加したら画面上部までスクロールするなどの処理を実装する際に使えそうです。
Vue2
<script>
export default {
updated() {
console.log("updated");
},
};
</script>
beforeUpdateとupdated内で同じdataに対して更新をかけると無限ループに入るでご注意!
特定の
dataの変更を検知してなんらかの処理を実行したい場合は、Vueのウォッチャー(watch)を使用することを推奨します。
Vue3
<script setup lang="ts">
import { onUpdated } from "vue";
onUpdated(() => {
console.log("updated");
});
</script>
beforeDestroy / beforeUnmount
Vueインスタンスが破壊される前に実行されるフックです。
Vue2ではbeforeDestroy、Vue3ではbeforeUnmountというメソッド名になります。
リソースの解放やイベントリスナーのクリーンアップ(メモリリークを防ぐ為にaddEventListenerで設定したイベントをremoveEventListenerで破棄する)など、インスタンスのクリーンアップに関連する処理を記載する場所として適しています。
Vue2
<script>
export default {
beforeDestroy() {
console.error("before destroy");
},
};
</script>
Vue3
<script setup lang="ts">
import { onBeforeUnmount } from "vue";
onBeforeUnmount(() => {
console.log("before unmount")
});
</script>
destroyed / unmounted
Vueインスタンスが破壊された後に実行されるフックです。
Vue2ではdestroyed、Vue3ではunmountedというメソッド名になります。
コンポーネントが完全にアンマウントされた後の後処理やリソース解放などを行うのに適しています。
Vue2
<script>
export default {
destroyed() {
console.error("destroyed");
},
};
</script>
Vue3
<script setup lang="ts">
import { onUnmounted } from "vue";
onUnmounted(() => {
console.log("unmounted")
});
</script>
まとめ
| ライフサイクルフック名 | 実行タイミング |
|---|---|
beforeCreate |
data、methods等の初期化前 |
created |
data、methods等の初期化後 |
beforeMount |
<template>がHTMLに変換される前 |
mounted |
<template>がHTMLに変換された後 |
beforeUpdate |
dataが更新され、DOMに反映される前 |
updated |
dataが更新され、DOMに反映された後 |
beforeDestroy / beforeUnmount
|
Vueインスタンスを破棄する前 |
destroyed / unmounted
|
Vueインスタンスを破棄した後 |
