【Vue + vue-cli】Vueにおけるライフサイクルについて
目次
今回はVue.jsにおけるライフサイクルについて触れていきたいと思います。
ライフサイクルを理解することはVueを理解する上で欠かせない要素です。
今回はその概要と各ライフサイクルフックの性質を解説していきたいと思います。
尚、今回使用するデータは以下の記事のものを使います。
https://www.dailyupblog.com/web_development/742/
先に上記記事をご覧になることをお勧めいたします。
ライフサイクルとは?
Vue.jsではインスタンスが生成されてから破棄されるまでの一連の流れのことをライフサイクルと呼びます。
ライフサイクルの中において、インスタンスの生成や、DOM要素へのマウント、インスタンスを破棄する時など、それぞれのタイミングでコードを追記できます。
そして、それぞれのタイミングの性質によってできることが変わってきます。
下記はVue公式サイトに載っているライフサイクルの図解です。
上記の図がライフサイクルの一連の流れです。
ライフサイクルフック
ライフサイクル上にはそれぞれコードを関数にて追記できるタイミングがあります。
この関数のことをライフサイクルフックと呼びます。
ライフサイクルフックを大まかに表にまとめました。
beforeCreate | インスタンスの生成時、データが初期化される前 |
created | インスタンス生成後、データが初期化された後 |
beforeMount | インスタンスがDOM要素にマウントされる前 |
mounted | インスタンスがDOM要素にマウントされる後 |
beforeUpdate | データ更新後、DOMに反映される前 |
updated | データ更新後、DOMに反映された後 |
beforeDestroy | インスタンスが破棄される前 |
destroyed | インスタンスが破棄された後 |
特に暗記するべきことではありませんが、ライフサイクルでは上記のような種類があります。
それでは実際にそれぞれ見ていきましょう。
beforeCreate、created
インスタンス生成後のデータ初期化の前後のフックです。
beforeCreateはデータ初期化前に呼ばれるため、このタイミングでdataオブジェクトなどを参照しようとしても、取得できません。
「pages」フォルダ内のTop.vueを開いて、下記のように記述してください。
<template>
<main>
<h2>{{title}}</h2>
</main>
</template>
<script>
export default {
data () {
return {
title: ""
}
},
beforeCreate () {
this.title = "create前です。"
},
}
</script>
<style scoped>
main {
height: calc(100vh - 152px);
padding: 3% 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
h2 {
margin: 0;
}
</style>
これでページを確認してみると、「create前です。」のテキストの表示は確認できません。
データ初期化前で、dataをも参照ができないタイミングなため、取得できていません。
createdではDOMが生成していないタイミングなため、DOMを取得、操作することができません。dataオブジェクトやメソッドなどを参照することはできます。
同じく、Top.vueを開いて、下記のように記述してみてください。
<template>
<main>
<h2>{{title}}</h2>
</main>
</template>
<script>
export default {
data () {
return {
title: ""
}
},
created () {
this.title = "create後です。"
}
}
</script>
<style scoped>
main {
height: calc(100vh - 152px);
padding: 3% 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
h2 {
margin: 0;
}
</style>
これでページを確認すると「create後です。」のテキストが表示されます。
createdではデータ初期化後で、dataを参照可能なため、問題なくデータを取得して、表示されていることがわかります。
beforeMount、mounted
DOMにインスタンスがマウントする前後でのフックです。
beforeMountはDOMが生成する前のため、created同様DOMの取得、操作をすることができません。
Top.vueを開いて下記のように記述してみてください。
<template>
<main>
<h2>{{title}}</h2>
</main>
</template>
<script>
export default {
data () {
return {
title: ""
}
},
beforeMount () {
const targetElement = this.$el;
console.log("対象のDOM:", targetElement);
}
}
</script>
<style scoped>
main {
height: calc(100vh - 152px);
padding: 3% 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
h2 {
margin: 0;
}
</style>
DOMのルート要素を取得するには「this.$el」で取得することができます。
これでページを開き、ディベロッパーツールでコンソールを見てみると、「対象のDOM: undefined」となり取得されていません。
DOM生成前で、DOMの取得・操作ができないため、ルート要素が取得できていないことがわかります。
mountedはDOMが生成された後なので、DOMの取得、操作を行うことができます。
もちろん、element(this.$el)にアクセスすることができます。
ただ、子コンポーネントまで完全に反映されるまで時間がかかる場合があるため、それを待つ場合は「$nextTick」を使用します。
Top.vueを開いて下記のように記述してください。
<template>
<main>
<h2>{{title}}</h2>
</main>
</template>
<script>
export default {
data () {
return {
title: ""
}
},
mounted () {
const targetElement = this.$el;
console.log("対象のDOM:", targetElement);
}
}
</script>
<style scoped>
main {
height: calc(100vh - 152px);
padding: 3% 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
h2 {
margin: 0;
}
</style>
上記でコンソールを確認してみると、ちゃんとルート要素が表示されていると思います。
createdではDOMを取得・操作できることがわかりました。
ちなみにフックが子コンポーネントまで完全にマウントされるまで待ってから実行するために「$nextTick」を使う場合は以下のように記述してください。
mounted () {
this.$nextTick(() => {
// レンダリング後の処理
});
}
beforeUpdate、updated
データが更新され、DOMに反映される前後でのフックです。
APIなどを叩いて、データを取得し、更新、DOMに反映させるタイミングで使われることが多いです。
beforeUpdate() {
// 更新前の処理
},
updated() {
// 更新後の処理
}
beforeDestroy、destroyed
ライフサイクルの後半、インスタンスが破棄される前後のフックです。
beforeDestroyの時点では、インスタンスはまだまだ機能しています。
destroyedの時点ではインスタンスは機能しておらず、全て破棄済みです。
beforeDestroy() {
// 破棄前の処理
},
destroyed() {
// 破棄後の処理
}
まとめ
一点注意点があるのですが、このライフサイクルは同期処理的に動作するものなので、非同期処理をライフサイクル内で使った場合、意図したフック通りの処理にならないことがあります。
今回はライフサイクルの概要について触れました。
ライフサイクルを理解することで、正しいタイミングで処理を書くことができます。
処理タイミングによるエラーについてもライフサイクルを理解しておけば、対処できると思います。
それでは今回はここまで。
お疲れ様でした!
Vueライフサイクル公式
https://jp.vuejs.org/v2/guide/instance.html