LoginSignup
36
30

More than 5 years have passed since last update.

Vueのライフサイクル

Last updated at Posted at 2018-11-18

Vueのライフサイクルとは

Vueインスタンスの生成から消滅までの一連の過程のこと。
この過程における、特定のタイミングで処理を割り込ませる仕組みがライフサイクルフックと呼ばれる。
公式ドキュメントにざっくりと一連のフローが書いてあります。
Vue.jsでは、いくつかフックが用意されている。

コンポーネント

説明にあたって以下のようなコンポーネントを想定する。
概要は、スタイルデータを用意し、横幅が拡大するボタンを設置しただけのコード。
フック等は適宜示すので省略してます。

app.vue
<template>
  <div id="app" :style="appStyle">
    <button @click="extendWidth">extend</button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      appStyle: {
        width: '120%',
        height: '100%'
      }
    }
  },
  methods: {
    extendWidth () {
      this.appStyle.width = parseInt(this.appStyle.width) + 10 + '%'
    }
  }
}
</script>

beforeCreate

Vueインスタンスを生成し、データが初期化がされる前に一度だけ呼ばれるフック。
リアクティブデータが初期化される前なので、この時点でdataプロパティ等を参照しても何もありません。


beforeCreate: {
  console.log(this.appStyle.width) // 'undefined'
  this.extendWidth // "this.extendWidth is not a function"
}

created

Vueインスタンスを生成し、データが初期化がされた後に一度だけ呼ばれるフックです。
ここでリアクティブデータやメソッド等を参照できます。


created: {
  console.log(this.appStyle.width) // '120%'
  // this.extendWidth // Methods are also accessible
}

axiosを利用してAPIからデータを取得するタイミングはここがいいです。

beforeMount

VueインスタンスがDOMにマウントされる前に一度だけ呼ばれるフックです。
この時点までのライフサイクルでは、DOMの操作を行うことはできません。

beforeMount () {
  // Error
  console.log(this.$el.clientWidth)
},

mounted

VueインスタンスがDOMにマウントされた後に一度だけ呼ばれるフックです。
ここでDOMにアクセスできます。

mounted () {
  console.log(this.$el.clientWidth) // 横幅のピクセル
  console.log(this.$el === document.getElementById('app')) // true
}

$elはルートなDOMを参照するWeb APIです。
生jsのdocument.getElementByIdに相当し、等価演算でtrueを返します。

window.addEventListenerでのイベントリスナはここで定義するといいです。

beforeUpdate

イベントハンドラ等からメソッドを実行するなどしてデータが変更され、
変更されたデータがDOMに反映される前に呼ばれるフックです。

beforeUpdate () {
  console.log(this.appStyle.width) // (10増加して)'130%'
  console.log(this.$el.clientWidth) // '120%'分の横幅ピクセル
}

イベントを発火させて横幅のスタイルデータをいじったとしましょう。このとき、スタイルデータこそ更新されましたが、
この時点では変更されたスタイルデータがDOMに反映されていないため、
DOMからは増加する前の横幅が取得されます。

特定のデータの更新をトリガにするならwatcherを使った方がいいです。

watch: {
  'appStyle.width' () {
    console.log(this.$el.clientWidth) // '120%'分の横幅ピクセル
  }
}

これでwidthだけが更新されると後処理が実行されます。

watcherも同様に、データがDOMへ反映される前に実行されるので、
beforeUpdateフックのスコープが小さくなったバージョンと考えてもよさそうです。

updated

データが変更され、DOMに反映された後に呼ばれるフックです。

updated () {
  console.log(this.$el.clientWidth) // '130%'分の横幅ピクセル
}

ここでDOMに反映されます。DOMが更新された後の処理はこのフックで記述します。

こちらも代替として、$nexttickを使っても同じようにDOM反映後に処理が行えます。

methods: {
  extendWidth () {
    this.appStyle.width = parseInt(this.appStyle.width) + 10 + '%'
    this.$nextTick(function () {
      console.log(this.$el.clientWidth) // '130%'分の横幅ピクセル
    }
  }

beforeDestroy

vm.$destroy()がコールされると、Vueインスタンスを破棄します。
その破棄される前に呼ばれるフックです。

<button @click="destroyInstance">destroy</button>
methods: {
  destroyInstance () {
    this.$destroy()
  }

メモリリークの要因ともなるので、役目を終えたインスタンスは破棄していきたいですね。
https://jp.vuejs.org/v2/cookbook/avoiding-memory-leaks.html

destroyed

vm.$destroy()がコールされ、Vueインスタンスが破棄された後に呼ばれるフックです。
Vueインスタンスが破棄されると、以下のようになります。

  • watcherが停止する
  • イベントリスナが停止する(v-onディレクティブも同様)
  • 子コンポーネントも同様に影響する
36
30
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
36
30