はじめに
前回はv-ifの条件をurl(親のプロパティ)にしていたが、今回はchildUrl(子のdataプロパティ)にする
話すこと
前回と同じで、以下コードを例にどのライフサイクルフックをつかったら、どんな挙動を示すのかを順にみていく
やりたいこと
子コンポーネントで定義するimgタグのsrc属性の内容に応じて表示する画像を変更する
OKな時
NGな時
ソースコード
親コンポ―ネント
<template> <div> <ImageChildComponent :url="url" @replace="replaceUrl" ></ImageChildComponent> </div> </template> <script> import ImageChildComponent from './ImageChildComponent.vue' export default { components: { ImageChildComponent }, data() { return { url: '', } }, methods: { replaceUrl(newUrl) { console.log(newUrl); this.url = newUrl; }, } } </script>
親コンポーネントでやっていることは前回と変わらない
子コンポーネント
<template> <div> <!-- OK時の画像 --> <div v-if="childUrl" // 変更 > <h2>OK!!!</h2> <img :src="childUrl" width=200 > </div> <!-- NG時の画像 --> <div v-else > <h2>NG...</h2> <img src="../assets/no-image.png" width=200 > </div> </div> </template> <script> export default { props: { url: { type: String, default: "", }, }, data() { return { childUrl: '', } }, beforeCreate() { console.log('beforeCreate: ', this.childUrl); // const newUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='; // this.childUrl = newUrl; }, created() { console.log('created: ', this.childUrl); // const newUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='; // this.childUrl = newUrl; }, beforeMount() { console.log('beforeMount: ', this.childUrl); // const newUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='; // this.childUrl = newUrl; // console.log('beforeMount: ', this.childUrl); }, mounted() { console.log('mounted: ', this.childUrl); // const newUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='; // this.childUrl = newUrl; // console.log('mounted: ', this.childUrl); }, methods: { getUrl() { console.log('methods(getUrl): ', this.childUrl); // const newUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='; // this.childUrl = newUrl; // return this.childUrl; } } } </script>
<template>
でやっていることは基本的には一緒ですが、変化点は以下
- v-ifの条件が子コンポーネント特有のdataプロパティ
childUrl
になっている
<script>
でやっていることは前回と全く一緒
懸賞方法
前回同様、コメントアウトしてある箇所を随時コメントインして実行していく
デフォルト
ブラウザ
コンソール
- 今回はエラーがでずにchildUrlがundifiedになっている…
ギモン
- beforeCreateの時点ではdata()は実行されていないから、前回同様「childUrlなんてない!」って怒られてもいいと思うけど、なんで今回undefinedが定義されているんだろう…
beforeCreated
... beforeCreate() { console.log('beforeCreate: ', this.childUrl); const newUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='; this.childUrl = newUrl; }, ...
ブラウザ
デフォルトと同じなので割愛
コンソール
コチラもデフォルトと同じなので割愛
デフォルトでchildUrlを認識しているのであれば、beforeCreateでchildUrlにnewUrl代入すればDOMに反映されると思ったが、違った
created
created() { console.log('created: ', this.childUrl); const newUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='; this.childUrl = newUrl; console.log('created: ', this.childUrl); },
ブラウザ
コンソール
今までで一番Vueライフサイクルのイメージ通りの挙動した
consoleもcreatedでchildUrlにnewUrlを定義した後は、全てconsole.logでnewUrlの値が出力できている
beforeMount
beforeMount() { console.log('beforeMount: ', this.childUrl); const newUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='; this.childUrl = newUrl; console.log('beforeMount: ', this.childUrl); },
ブラウザ
createdと同じ
コンソール
こちらも想定通り
boforeMount以降はnewUrlが表示されている
mounted
mounted() { console.log('mounted: ', this.childUrl); const newUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='; this.childUrl = newUrl; console.log('mounted: ', this.childUrl); },
ブラウザ
created, beforeMouteと同じ
コンソール
mountedでnewUrlをchildUrlに代入しているので、mountedでdataが変更されたタイミングでre-renderingされ、mountedでconsoleに表示される
methods
ここで想定するのは以下のようなソースコード
<template> <div v-if="url" > <h2>OK!!!</h2> <img :src="getUrl()" // 変更 width=200 > </div> ... </template> <script> export default { ..., methods: { getUrl() { console.log('methods(getUrl): ', this.childUrl); const newUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='; this.childUrl = newUrl; return this.childUrl; } ... } </script>
ブラウザ
コンソール
- v-ifで表示childUrlがnullなので、常にno-imageが表示される
getUrlをv-ifで呼び出した場合
<div v-if="getUrl()" <!-- 変更 --> > <h2>OK!!!</h2> <img :src="getUrl()" width=200 > </div>
ブラウザ
コンソール
前回同様で
- mountedまでは1回めのDOM生成時(v-if, imgのsrc属性)のgetUrl呼び出し時のconsole
- mounted以降は2回目のDOM生成時のgetUrl呼び出し時のconsole
の出力結果
参考記事
https://jp.vuejs.org/v2/guide/instance.html#ライフサイクルダイアグラム
所見
- createdでdataプロパティの値を変更するとそれ以降のライフサイクルフックでも変更後の値が取得できる点から、一番Vueのライフサイクル通りの挙動をしていた
- 前回同様、最後のgetUrの例はライフサイクルを知るのにかなりわかりやすかった
- imgのsrcの変遷を追うことでだいぶ理解はできたと思う