生命週期函數就是 Vue 實例在某一個時間點會自動執行的函數。vue
簡單來講就是好像把人的出生到死亡分紅一個個階段,你取名字確定是在你出生階段,而不是在成年階段;你結婚確定是在成年階段,而不是在出生階段;若是說你在出生階段想去階段,那確定是不行的。
組件也是同樣,在實例化的時特定階段調用特定方法,調用的這個方法就是鉤子函數。segmentfault
鉤子函數和回調函數有什麼區別嗎?後端
它們區別是:app
js
派函數監聽事件 => 監聽函數就是所謂的鉤子函數 => 函數鉤取事件:函數主動找事件 => 鉤子函數
js
預留函數給dom
事件,dom
事件調用js
預留的函數 => 事件派發給函數:事件調用函數 => 回調函數dom
打個比方:異步
鉤子函數:一個房間裏的監控攝像頭監控着每個進入的人的面部特徵,識別出了符合條件的人就觸發警告(執行函數事件);回調函數:能夠看作是在一片地區埋了許許多多的地雷,一旦踩中了某個地雷(觸發事件),地雷就會爆炸(執行函數事件)。函數
能夠簡單的理解爲:post
鉤子函數是事件被動的監聽,一旦條件觸發就執行回調函數是主動事件,執行函數體內容動畫
<template> <div>{{msg}}</div> </template> <script> export default { name: 'HelloWorld', data () { return { msg: 'hello world', msg1: '' } }, beforeCreate () { console.groupCollapsed('beforeCreate 建立前狀態') console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el) console.log(this.$el) console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data) console.log(this.$data) console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg) console.groupEnd() }, created () { console.groupCollapsed('created 建立前狀態') console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el) console.log(this.$el) console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data) console.log(this.$data.msg) console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg) console.groupEnd() }, beforeMount () { console.groupCollapsed('beforeMount 掛載前狀態') console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el) console.log(this.$el) console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data) console.log(this.$data.msg) console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg) console.groupEnd() }, mounted () { console.groupCollapsed('mounted 掛載後狀態') console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el) console.log(this.$el) console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data) console.log(this.$data.msg) console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg) console.groupEnd() setTimeout(() => { this.$data.msg = '123' }, 5000) }, activated () { console.groupCollapsed('activated 掛載後狀態') console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el) console.log(this.$el) console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data) console.log(this.$data.msg) console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg) console.groupEnd() setTimeout(() => { this.$data.msg = 'hello tiantian' }, 10000) }, beforeUpdate () { console.groupCollapsed('beforeUpdate 更新前狀態') console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el) console.log(this.$el) console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data) console.log(document.getElementById('app').innerHTML) console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg) console.groupEnd() }, updated () { console.groupCollapsed('updated 更新後狀態') console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el) console.log(this.$el) console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data) console.log(document.getElementById('app').innerHTML) console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg) console.groupEnd() setTimeout(() => { this.$destroy() }, 5000) }, beforeDestroy () { console.groupCollapsed('beforeDestroy 實例銷燬前狀態') console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el) console.log(this.$el) console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data) console.log(document.getElementById('app').innerHTML) console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg) console.groupEnd() }, destroyed () { console.groupCollapsed('destroyed 實例銷燬後狀態') console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el) console.log(this.$el) console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data) console.log(document.getElementById('app').innerHTML) console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg) console.groupEnd() } } </script>
beforeCreate
和created
beforeCreate
:在實例初始化完成時,被執行
created
:在初始化結束以後會再初始化一些外部注入和一些雙向綁定相關的事情時,被執行this
這兩個鉤子函數執行完以後,初始化基本完成了。
在beforeCreate
階段,el
和data
都沒有被掛載;而在created
階段,el
還沒被掛在,但data
已經被掛載了,以下圖所示:
這裏el
爲啥沒有被掛載呢?
看上圖,在created
執行完畢後,它會詢問一個條件:你這個Vue
實例裏是否有el
這個選項。
若是有就又會詢問是否有template
這個選項:
若是沒有template
就會走右側的分支,
template
,就會將el
這個根節點當作模版,來進行渲染若是有template
就會走左側的分支
template
做爲模版去渲染beforeMount
和mounted
beforeMount
:執行時,頁面尚未被渲染
mounted
:執行時,頁面已經被渲染了
從圖中也能夠看出,在beforeMount
執行時,el
尚未被掛在;當mounted
執行時,el
被掛載到頁面了。
beforeUpdate
和updated
beforeUpdate
:數據被改變,還沒渲染以前會被執行
updated
:數據被改變,渲染完成後會被執行
這張圖中有個奇怪的現象,爲何在beforeUpdate
和updated
兩個鉤子函數中,el
和msg
都是同樣呢?beforeUpdate
執行是不該該是老數據嘛,怎麼這裏也是最新的數據了?
由於這裏的el
是虛擬dom
,不是真實的dom
,和data
都是對象,在加上console.log
這裏是個異步操做,當你點開console.log
時,其實代碼早就跑完了,數據已是最新的了,因此就會看到在這兩個函數中輸出結果是同樣的了。
能夠用document.getElementById('app').innerHTML
獲取真實的Dom
結構,這時咱們就能夠看到這兩處不同的地方了。
beforeDestroy
和destroyed
調用vm.$destroy()
方法可對實例銷燬
beforeDestroy
:實例被銷燬前被執行
destroyed
:實例被銷燬後被執行
activated
和deactivated
使用keep-alive
標籤後,會有兩個生命週期函數分別是:activated
、deactivated
activated
:頁面展現的時候被執行
deactivated
:頁面被隱藏或者頁面即將被替換成新的頁面時被執行
created
:掛載以前須要作的一些事情能夠在放在這裏面,好比頁面加載時loading
動畫
mounted
:向後端發請求,能夠放在這個函數中。
這兩個鉤子函數使用時機重疊部分不少,反正是怎麼方便怎麼來就是了。