參考原文:https://m.html.cn/qa/vue-js/22535.html
Vue 中 生命周期鈎子函數分別做了什么?
beforeCreate執行時:data / el 未初始化,值為undefined
created執行時:可得到 data 的值,但 根 dom元素 el 還未初始化。
可對 data 進行操作,進行數據請求將返回的數據賦給 data。
beforeMount執行時:data / el 已初始化,但此時 el 並沒有渲染進數據,el 的值為“虛擬”的元素節點
mounted執行時:el 已渲染完成並掛載到實例上
對掛載的 dom 進行操作,此時,dom已被渲染到頁面上。
beforeUpdate 和 updated 觸發時:el 中的數據已渲染完成,但只有 updated鈎子被調用時,組件dom才被更新。
雖然updated函數會在數據變化時被觸發,但卻不能准確的判斷是哪個屬性值被改變,所以在實際情況中用 computed / watch 來監聽屬性的變化,並做一些其他的操作。
所有的生命周期鈎子自動綁定 this 上下文到實例中,所以不能使用箭頭函數來定義一個生命周期方法(例如:created: () => this.fetchTodos() ),會導致this指向父級
在使用vue-router 時,有時需要使用緩存組件狀態,這時候created鈎子就不會被重復調用,如果子組件需要在每次加載或切換狀態的時候進行某些操作,可以使用 activated 鈎子觸發。
注意:activated,deactivated 是組件 keep-alive 時獨有的鈎子
父子組件的鈎子並不會等待請求返回,請求是異步的,VUE 設計也不能因為請求沒有響應而不執行后面的鈎子。所以,我們必須通過 v-if 來控制子組件鈎子的執行時機。
注意:
在父組件的 created 中發請求獲取數據,通過props傳遞給子組件。子組件在 created 或者mounted中拿父組件傳遞過來的數據 ,這樣處理是有問題的。
在父組件調用接口傳遞數據給子組件時,接口響應顯然是異步的。這會導致無論你在父組件哪個鈎子發請求,在子組件哪個鈎子接收數據。都是取不到的。當子組件的mounted都執行完之后,此時可能父組件的請求才返回數據。會導致:從父組件傳遞給子組件的數據是 undefined
解決方法1 :
在渲染子組件的時候加上一個條件,data1 是父組件調用接口返回的數據。當有數據的時候再去渲染子組件。這樣就會形成天然的阻塞。在父組件的 created 中的請求返回數據后,才會執行子組件的 created,mounted。最后執行父組件的mounted。
<div class="test"> <children v-if="data1" :data="data1" /> </div>
解決方法2:
在子組件中 watch 監聽,父組件獲取到值,這個值就會變化,自然是可以監聽到的。
從父組件點擊調用接口並顯示子組件,子組件拿到數據並監聽在 watch 中調用方法並顯示
以下為子組件。data1 是從父組件傳遞過來的數據。在 created,mounted中都拿不到父組件調用接口返回的data1。只能 watch 監聽 data1,並調用方法渲染子組件。
props:['data1'], watch:{ data1:{ deep: true, handler: function(newval, oldval){ this.$nextTick(() => { this.data1 = newval this.showData1(this.data1) }) } } }
Vue 的 父子組件的生命周期執行順序
Vue 的父組件和子組件的生命周期鈎子函數執行順序可以歸類為以下 4 部分:
1、加載渲染過程
父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子beforeMount -> 子 mounted -> 父 mounted
注意:mounted 不會保證所有的子組件也都被一起掛載。如果希望等到整個視圖都渲染完畢,可以在 mounted 內部使用 vm.$nextTick
2. 父組件更新過程
父 beforeUpdate -> 父 updated
3. 子組件更新過程
父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
4. 銷毀過程
父 beforeDestroy -> 子 beforeDetroy -> 子 destroyed -> 父 destroyed