下面先附上官網的一張圖示,附有註釋講解。隨著你的不斷學習和使用,它的參考價值會越來越高。
所有的生命週期鉤子自動繫結this
上下文到例項中,因此你可以訪問資料,對屬性和方法進行運算。這意味著你不能使用箭頭函式來定義一個生命週期方法 (例如created: () => this.fetchTodos()
)。這是因為箭頭函式繫結了父上下文,因此this
與你期待的 Vue 例項不同。
beforeCreate
在例項建立之前,data中的資料,methods、watch、computed裡的方法都還不能訪問 列印出來全都是undefined。那麼問題來了:如何在這個生命週期獲取data中的資料呢?
非同步方式獲取data:this.$nextTick或者setTimeout都行。相當於在初始化前告訴容器,等整個檢視都渲染完畢再跑裡面的程式碼。這種方式別說拿data了,拿渲染完DOM都OK~
同步方式獲取data: 在beforeCreate前,所有的options都會先存到vm.$options
中, 就是直接從this.$options.data
裡去拿。比如this.$options.data()[key]
就好。如下:
export default {
name: 'App',
data () {
return {
b: {
name: 'clearlove'
}
}
},
beforeCreate () {
console.log(this.$options.data()['b'], '例項建立之前') //{ name: 'clearlove'} '例項建立之前'
}
}
// this.$options.data就是上方的data函式複製程式碼
但是實際情況中,從來沒遇到過需要在元件還沒初始化就去拿data的……
created
例項已經建立,可以直接使用例項中的資料和方法,但是還不能對DOM節點進行訪問。即$el屬性不可見。該階段允許進行非同步請求
<template>
<div id="app">
<div id="nav" ref="myDiv"></div>
</div>
</template>
<script>
export default {
created () {
console.log(this.$refs.myDiv, '例項建立完成') // undefined '例項建立完成'
}
}複製程式碼
beforeMount
相關的 render
函式首次被呼叫。
mounted
相關的 render
函式首次被呼叫。DOM節點已經渲染,可以進行DOM操作,比如事件監聽。該階段允許進行非同步請求,但是如果是父元件非同步獲取資料要使用props傳遞給子元件的話,則要在created裡去發非同步請求。具體原因看下方父子元件的生命週期
beforeUpdate
資料更新時呼叫,發生在虛擬 DOM 打補丁之前。這裡適合在更新之前訪問現有的 DOM,比如手動移除已新增的事件監聽器。可以修改data,並不會觸發附加的衝渲染過程。這裡的$el物件已經修改,但是頁面上的資料還沒有發生改變。
updated
DOM結構上的資料已經完成更新。若再次修改data,會再次觸發beforeUpdate、updated,進入死迴圈。
beforeDestroy
例項被銷燬前呼叫,也就是說在這個階段還是可以呼叫例項的。
例項的銷燬,vue例項還是存在的,只是解綁事件的監聽和資料與view的繫結,即資料驅動。
destroyed
例項被銷燬後呼叫,所有的事件監聽器已被移除,子例項被銷燬。
這裡再簡單說一下父子元件的生命週期:
- 載入渲染過程:
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
- 子元件更新過程:
父beforeUpdate->子beforeUpdate->子updated->父updated
- 父元件更新過程:
父beforeUpdate->父updated
- 銷燬過程:
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
總結
Vue的生命週期函式為開發者提供了非常便利的操作。但是善用生命週期才會不踩坑,掌握好Vue的生命週期是非常重要的。它能在很大程度上減少我們日常開發的BUG。
一定需要注意資料獲取是個非同步過程,而生命週期函式的執行是獨立的!只要涉及到DOM更新的操作,推薦大家使用Vue的自帶方法$nextTick。這個方法的意思是把回撥函式內的操作延遲到下一個DOM更新迴圈之後。Vue本身會將所有DOM更新的操作放入一個佇列裡,$nextTick就是會將方法內回撥函式的操作延遲到佇列裡下一個DOM更新後執行。