vue.jsのライフサイクルの説明を目にする機会は多いですが、文書だけで説明してる場合が多く初心者の人が理解するのは難しいです。利用頻度の高いcreated, mountedだけでもはっきり区別がつけばライフサイクル図の理解もできるかもしれません。今回はvue.jsのcreatedとmountedの違いを主に要素elを使って説明してみます。

vue.jsの公式サイトに掲載されているライフサイクル図。今回はこの図の中でelとライフサイクルフックcreated, mounted, beforeCreateにのみ注目します。

vue.jsライフサイクル
vue.jsライフサイクル

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

created, mountedはライフサイクルフックと呼ばれ、vue.jsの初期化の決められたタイミングで実行される関数です。ライフサイクルフックの中にプログラムを記述するとvue.jsの初期化の流れの中でその関数が必ず自動で実行されます。

初期化とはvue.jsが使えるようになるまでの処理です

APIなどを利用して外部からデータを取得してブラウザに表示させたい場合は、ライフサイクルフックの中でaxiosなど利用してデータ取得のプログラムを記述しておきます。ライフサイクルフックの中にプログラムを記述することでvue.jsの起動中にデータの取得を開始し、取得が完了するとブラウザにそのデータ内容を表示させることができます。

elがなにか確認してみよう

ライフサイクルを記述した上の図に”el”という文字列を見つけることができます。elはvue.jsインスタンスがmountを行う要素で、elが指定された要素の中でだけvue.jsを動かすことができます。new Vueで下記のようにして#appといった要素を特定するidの値を記述します。


var app = new Vue({
  el: '#app',
  data: {

  },
})

このelが一体どのような情報を持っているのか確認してみましょう。elにはthis.$elでアクセスすることができます。

button要素を作ってv-onディレクティブでclickイベントを設定し、クリックが行われたらshowElメソッドを実行しコンソールにthis.$elの中身を表示させます。


<body>
  <div id="app">
    <h1>Hello World</h1>
    <button v-on:click="showEl">show el</button>
  </div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
  el: '#app',
  data: {
  },
  methods:{
    showEl : function(){
      console.log(this.$el)
    }
  }
})
</script> 
</body>

デベロッパーツールのコンソールに<div id=”#app”></div>が表示されます。つまり中身は、document.getElementById(’app’)を使って取得できるものと同じです。

this.$elの中身を表示
this.$elの中身を表示

getElementById(‘app’)で取得できる要素と同じなので、innnerHTMLで中身を書き換えることも可能です。buttonをクリックするとHello WorldがHello Vueに書き換えられることが確認できます。


this.$el.innerHTML = "<h1>Hello Vue</h1>";

elはnew Vueインスタンスで指定した要素であることがわかりました。

createdとmountedの違い

elの中身がわかったので、ライフサイクルフックのcreatedとmountedの違いを確認しておきましょう。createdとmountedの違いは下記のように説明されているのをよく見かけます。

createdはDOMがまだ作られていない状態で、mountedではDOMが作成された直後の状態です。

DOMの作成、未作成でライフサイクルフックの違いが別れているということなので、this.$elを使ってその違いを確認してみましょう。確認方法はシンプルでcreatedとmountedにconsole.logでthis.$elがそれぞれの状態でどのようになっているか確認するだけです。

this.$elはDOMの要素なのでDOMが作成されていないとthis.$elは存在しません。


new Vue({
  el: '#app',
  data: {
  },
  created : function(){
    console.log('created')
    console.log(this.$el)
  },
  mounted : function(){
    console.log('mounted')
    console.log(this.$el)
  }
})

createdではDOMが作成されていないので、this.$elはundefinedとなっており、mountedではDOMの作成が完成しているので<div id=”app”></div>が表示されます。

createdとmountedでのthis.$elの状態
createdとmountedでのthis.$elの状態

これでcreated, mountedの違いがわかりました。そのため、createdの時にgetElementById(‘id’)を使ってなにかDOMの要素を取得しようとしても取得することはできません。しかしmounted時にはDOMの作成が完了しているのでDOMの要素が取得できるためgetElementByIdだけではなくvue.js以外のライブラリjQuery等(DOMを利用するもの)もこの時点で使用可能となります。

createdでは何が完了しているのか

ではcreatedでは何が完了しているのでしょう。先程まではthis.$elでelの状態を確認しましたが、その中身は見えませんでした。今度はthisを使ってVueインスタンスを確認します。今回はdataにmessageプロパティの設定も行っておきます。


  el: '#app',
  data: {
    message : 'Hello World'
  },
  created : function(){
    this.message = 'Hello Vue'
    console.log('created')
    console.log(this)
  }

Vueインスタンスの作成が完了しているので、設定しているmessageをVueの中で確認することができます。this.messageをcreatedの中で上書きした値も反映されていることが確認できます。これでcreatedでインスタンスの作成が完了、dataオブジェクトがリアクティブになっているという説明を受けても理解することができます。

createdの状態でVueインスタンスを確認
createdの状態でVueインスタンスを確認

dataオブジェクトがリアクティブになっているのでcreatedの中でAPIを使ってデータ取得を開始しても問題がないこともわかります。このようなコードを見かけるのも納得できるかと思います。


  created :function(){
    axios.get('https://jsonplaceholder.typicode.com/usedrs')
          .then(response => this.users = response.data)
  }

createdとbeforeCreateの違い

beforeCreateでは、dataの中身を確認することができますが、createdのようにmessageの上書きを行うことはできません。


  beforeCreate : function(){
    
    this.message = 'Hello Vue'

    console.log('beforeCreate')
    console.log(this)
}
beforeCreateでdata変更

これでbeforeCreateでインスタンスの作成が完了、dataオブジェクトがリアクティブになっていないという説明を受けても理解することができます。

ここまでの説明を読み勧めていただければelの理解、beforeCreate, created, mountedのライフサイクルフックの違いも理解できたかと思います。