26
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Vue2 / Vue3】ライフサイクルフック

Last updated at Posted at 2023-08-06

ciclodevida-life-cycle.gif

ライフサイクルフックとは

Vueコンポーネントには、以下のようなライフサイクルが存在します。

  1. Vueインスタンスが作成される:create
  2. VueインスタンスがDOM要素にマウント(<template>内がHTMLに変換)される:mount
  3. リアクティブなデータが変更される:update
  4. Vueインスタンスが破棄される:destroy / unmount

これらそれぞれのタイミングの前後で自動的に呼び出される処理を定義することができるメソッドが、Vueでは用意されています。これを「ライフサイクルフック」と呼びます。

beforeCreate

dataなどの初期化前、何よりも最初に実行される処理を記載するフックです。

この時点ではdatamethodsなどの初期化は完了していないので、リアクティブなデータやイベントリスナーなどを利用(dataの値を変更したり、参照したり)できません。

その為、dataが関わらない(リアクティブ性が必要ない)処理を一番最初に行いたい際に有効です。

認証チェックのAPIなどをここで実行するのはありかなあとは思いますが、あまりbeforeCreateを使用しているケースを見たことがありません。

Vue2

<script>
export default {
  data () {
    return {
      name: "",
    };
  },
  beforeCreate() {
    console.log("Before create");
  },
};
</script>

Vue3

Vue2でbeforeCreatecreatedの中で表現していた処理は、setup内にそのまま処理を記載するような形になりました。

最初に実行される処理としてわかりやすいように、初期表示処理を即時関数として定義することをオススメします。

<script setup lang="ts">
import { ref } from "vue";

(() => {
  console.log("Before create");
})();

const name = ref<string>("");
</script>

created

datamethodsの初期化は完了しているが、DOM(<template>の中)は生成されていない状態で実行されるフックです。

beforeCreated内ではdatamethodsの初期化が完了していなかった為アクセスすることができませんが、この時点からアクセスすることが可能です。

初期遷移時、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同様、datamethodsの初期化は完了しているが、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>

余談: createdmountedについて

よく違いが曖昧になりがちなcreatedmountedですが、

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>

beforeUpdateupdated内で同じ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 datamethods等の初期化前
created datamethods等の初期化後
beforeMount <template>がHTMLに変換される前
mounted <template>がHTMLに変換された後
beforeUpdate dataが更新され、DOMに反映される前
updated dataが更新され、DOMに反映された後
beforeDestroy / beforeUnmount Vueインスタンスを破棄する前
destroyed / unmounted Vueインスタンスを破棄した後
26
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?