組件相關鉤子函數: beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destoryed
還有兩個特殊的(使用keep-alive):activated、deactivated(不詳述)
v2.5.0+新增: errorCaptured (暫時還不知道咋用)html
路由守衛:
全局&路由獨享:beforeEach、beforeResolve(v2.5.0+新增)、afterEach ;beforeEnter(路由獨享,相似beforeEach)
組件內:beforeRouteEnter、beforeRouteUpdate (2.2 新增)、beforeRouteLeavevue
實例初始化以後git
this指向建立的實例
數據觀測(data observer)和event/watcher配置還沒有完成
不能訪問到methods、data、computed、watch上的方法和數據github
實例建立完成,並已經完成如下配置:數據觀測(data observer),屬性和方法的運算, watch/event 事件回調
此時能夠調用methods中定義的方法,修改data的數據,而且可觸發響應式變化、computed值從新計算,watch到變動等ajax
還未掛載到DOM,不能訪問到$el屬性,$ref屬性內容爲空數組vue-router
new Vue({ data () { return { a : 1 } } , created (){ console.log( this.a ) // 1 } })
這個生命週期階段比較經常使用,好比ajax請求獲取初始化數據對實例進行初始化預處理等操做;但要注意在結合vue-router使用時,進入created生命週期階段後是沒法對掛載實例進行攔截的,此時實例已經建立完成;故若是須要某些數據獲取完成狀況才容許進入頁面的場景,建議在路由鉤子beforeRouteEnter中實現api
在掛載開始以前被調用數組
注意:從vue生命週期圖能夠看出
當new Vue({...})的配置中沒有el屬性時,生命週期暫停,等待vm.$mount(el)調用時才繼續瀏覽器
beforeMount以前,會找到對應的template,並編譯成render函數
(這個步驟若是使用.vue文件和運行時版本將會在構建時提早完成)app
template查找的優先級順序:
template參數 > el 外部HTML
若是指定了render函數,則直接採用render函數,即忽略template參數和el外部HTML
寫個栗子測試:
<div id="app">template outside</div> ... import App from './App.vue'; // App是任一Vue組件對象 new Vue({ el: '#app', // template: '<p>template inside</p>', // part inside // render: h => h(App) // part render })
須要Vue完整版本支持,註釋part inside和part render依次打開便可觀察到三次不一樣的結果
Vue的編譯過程暫略
el被新建立的$el替換 ---- 怎麼理解?
這個能夠理解爲掛載前爲實例尋找了一個暫時容身之處el,編譯完成($el建立完成)後替換這個容身之處完成實例的掛載
如:以前那個栗子中,將part render打開後觀察生成的DOM結構,<div id="app">template outside</div>
這個節點即原el已經被替換掉
實例掛載到DOM上,此時能夠經過DOM API獲取到DOM節點,$ref屬性能夠訪問
雖然常常觀察到先進入子組件mounted,但根據Vue官方文檔:
注意 `mounted` 不會承諾全部的子組件也都一塊兒被掛載。若是你但願等到整個視圖都渲染 完畢,能夠用 [vm.$nextTick](https://cn.vuejs.org/v2/api/#vm-nextTick)
在這個階段改變data上的值,相關的computed屬性能夠馬上更新;但須要進入到下一次DOM更新,才能看到DOM上數據更新
栗子:
new Vue({ el: '#app', template: '<p id="testa">{{a}}</p>', router, data () { return { a : 0 } }, mounted() { this.a ++; console.log(this.b); // 2 console.log(document.getElementById('testa').innerHTML) // 0 }, computed :{ b (){ return this.a+1; } } })
beforeRouteEnter的next的勾子比mounted觸發還要靠後 - 這個待會說到路由相關鉤子時再展開
這裏的更新對象是模板,即須要虛擬 DOM 從新渲染和打補丁,beforeUpdate發生在以上兩個流程以前,此時新的虛擬DOM已經生成
若是發生變動的數據在模板中並無使用(包括直接和間接,間接:好比某個依賴該數據的計算屬性在模板中使用了),則不會觸發更新流程!!!
如:
new Vue({ el: '#app', template: '<p id="testa">{{a}}</p>', router, data () { return { a : 0, b : 1 } }, mounted (){ this.b ++; // b並無在模板中使用 }, beforeUpdate (){ debugger; // 不會進入這個斷點 } })
在一些參考文章中看到:在這個鉤子函數中,能夠對狀態進行進一步更改,不會再次觸發重渲染流程
--- 這個說法有問題
若是對狀態進行變動會致使從新進入beforeUpdate(這裏變動的狀態一樣要在模板中使用,若是變動沒有在模板中使用的data,纔不會再次觸發重渲染流程)
並且若變動操做不是基礎類型的簡單賦值,還會引發死循環(不斷從新進入beforeUpdate)!
看看這個栗子,依次把註釋打開測試
new Vue({ el: '#app', template: '<p id="testa">{{a}}</p>', router, data () { return { a : 0, c: 0 } }, beforeUpdate() { console.log(document.getElementById('testa').innerHTML) // this.c = 1; // this.c沒有在模板中使用,變動不會引發重渲染流程 // this.a = 3; // 會再次進入一次重渲染流程,第二次進入時發現a還是3,值沒有變動,不會再次重渲染 // this.a ++; // 會引發死循環,每次進入重渲染流程時,a的值都會變動 }, updated() { console.log(document.getElementById('testa').innerHTML) } })
應該避免在這個鉤子函數中操做數據
因爲數據更改致使的虛擬 DOM 從新渲染和打補丁,在這以後會調用該鉤子。
當這個鉤子被調用時,組件 DOM 已經更新,能夠執行依賴於 DOM 的操做
注意 `updated` 不會承諾全部的子組件也都一塊兒被重繪。若是你但願等到整個視圖都重繪完畢, 能夠用 [vm.$nextTick](https://cn.vuejs.org/v2/api/#vm-nextTick)
一樣,應該避免在這個鉤子函數中操做數據
實例銷燬以前調用。在這一步,實例仍然徹底可用,this仍能獲取到實例
通常在這一步中進行:銷燬定時器、解綁全局事件、銷燬插件對象等操做
Vue 實例銷燬後調用。調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬
注意:vue2.0以後主動調用$destroy()不會移除dom節點,做者不推薦直接destroy這種作法,具體參考https://github.com/vuejs/vue/...,若是實在須要這樣用能夠在這個生命週期鉤子中手動移除dom節點
全局前置守衛
當一個導航觸發時,全局前置守衛按照建立順序調用。守衛是異步解析執行,此時導航在全部守衛 resolve 完以前一直處於 等待中
如何使用:
router.beforeEach((to, from, next) => { console.log('全局前置守衛:beforeEach -- next須要調用') next() })
通常在這個守衛方法中進行全局攔截,好比必須知足某種條件(用戶登陸等)才能進入路由的狀況
參數to和from都是路由對象Route
next是個Function,有如下幾種用法(from api文檔)
next
的參數是一個 Error
實例,則導航會被終止且該錯誤會被傳遞給 router.onError()
註冊過的回調全局解析守衛
和beforeEach相似,區別是在導航被確認以前,同時在全部組件內守衛和異步路由組件被解析以後,解析守衛就被調用
即在 beforeEach 和 組件內beforeRouteEnter 以後
參數和beforeEach一致,也須要調用next對導航確認
全局後置鉤子
在全部路由跳轉結束的時候調用
這些鉤子不會接受 next 函數也不會改變導航自己
可直接定義在路由配置上,和beforeEach方法參數、用法相同
在渲染該組件的對應路由被確認
前調用,用法和參數與beforeEach相似,next須要被主動調用
注意:
beforeRouteEnter (to, from, next) { // 這裏還沒法訪問到組件實例,this === undefined next( vm => { // 經過 `vm` 訪問組件實例 }) }
vm
訪問組件實例進行賦值等操做在當前路由改變,而且該組件被複用時調用,能夠經過this訪問實例, next須要被主動調用,不能傳回調
以前在手機瀏覽器中好像發現這個守衛的bug?@TODO 待確認
導航離開該組件的對應路由時調用,能夠訪問組件實例 this
,next須要被主動調用,不能傳回調
結合並擴展Vue-router官方文檔的說明:
非重用組件,開始組件實例的生命週期