Vue.js 親子コンポーネント間のライフサイクルフック
はじめに
・Vue.jsの単一コンポーネントのライフサイクルフックはこちらの記事などにもあるように、実装をするうえで避けては通れない概念です。
ただ、親子間のライフサイクルについて、あまり言及されている記事が無く、実装中に詰まった箇所がありましたので、こちらでまとめようと思います。
前提
Vue.jsのライブラリとしてVuetityを使用。
起こった事象
下記のような親子コンポーネントを想定する。
<template>
:
<v-row>
<v-expansion-panels accordion>
<v-expansion-panel @click="openAcordion()">
<v-expansion-panel-header>XXXX</v-expansion-panel-header>
<v-expansion-panel-content>
<Child
:reportText.sync="reportText"
:parentsParams="parentsParams"
/>
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
</v-row>
:
</template>
<script>
private mounted (): void {
this.parentsParams = 'thisIsTest'
}
</script>
<script>
mounted (): void {
this.getTextArea()
}
//バック側のAPIにパラメータをpostする処理を記述
~~~~~
</script>
■改修点
親コンポーネントを、アコーディオンメニューではなく、普通に表示をしたい。
v-row以下を下記のように修正したい
<v-row>
<v-col>
<Child
:reportText.sync="reportText"
:parentsParams="parentsParams"
/>
</v-col>
</v-row>
■エラーの内容
バック側にpostしたとき、親コンポーネントで定義しているはずのparentsParamsがnullだとエラーが出る。
(実際にAPIへpostをしているのはchildコンポーネント側)
■エラーの原因
子コンポーネントではparentsParamが定義されていないため
なぜ、parentsParamが定義されていなかったのか?
→親子間のライフサイクルの違い
◆親子間のライフサイクルフック
親created
↓
子created
↓
子mount
↓
親mount
上のように、親のmount時に定義しても、それより早く子の方がmountされるため、上記のようなエラーが出た。
改修時にこのエラーが起こったのは、
改修前はアコーディオンメニューを使っており、アコーディオンメニューボタンクリック時に
子コンポーネントが読み込まれる。つまり初期表示時のライフサイクルの影響を受けていなかった。
対策
子コンポーネントでmountされるよりも前に(つまり、親のcreated時など)値を定義する。
親子間でのデータ受け渡しがされている値は、どのタイミングで定義されているか、を常に意識しておく必要がある。
定義されているよりも前に使うとエラーになる。