vue官方文檔---實例生命週期
vue-router2.3版文檔---路由勾子
vue官方文檔---指令及其綁定週期html
在使用vue開發的過程當中,咱們常常會接觸到生命週期的問題。那麼你知道,一個標準的工程項目中,會有多少個生命週期勾子嗎?讓咱們來一塊兒來盤點一下:vue
根組件實例:8個 (beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed)node
組件實例:8個 (beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed)ajax
全局路由鉤子:2個 (beforeEach、afterEach)vue-router
組件路由鉤子:3個 (beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave)segmentfault
指令的週期: 5個 (bind、inserted、update、componentUpdated、unbind)dom
beforeRouteEnter的next所對應的週期ide
nextTick所對應的週期函數
嚇到了嗎?合計居然一共有28個週期,是否看得頭昏眼花了呢?接下來讓咱們一塊兒來介紹一下各個週期的一般用途與使用細節吧ui
這一塊vue2的官方文檔有一張圖示,咱們簡要提一下用法和注意
在實例初始化以後,數據觀測(data observer) 和 event/watcher 事件配置以前被調用。
tip: 此時組件的選項還未掛載,所以沒法訪問methods,data,computed上的方法或數據
實例已經建立完成以後被調用。在這一步,實例已完成如下的配置:數據觀測(data observer),屬性和方法的運算, watch/event 事件回調。然而,掛載階段還沒開始,$el 屬性目前不可見。
這是一個經常使用的生命週期,由於你能夠調用methods中的方法、改變data中的數據,而且修改能夠經過vue的響應式綁定體如今頁面上、獲取computed中的計算屬性等等。
tip: 一般咱們能夠在這裏對實例進行預處理。 也有一些童鞋喜歡在這裏發ajax請求,值得注意的是,這個週期中是沒有什麼方法來對實例化過程進行攔截的。 所以假若有某些數據必須獲取才容許進入頁面的話,並不適合在這個頁面發請求。 建議在組件路由勾子beforeRouteEnter中來完成。
在掛載開始以前被調用:相關的 render 函數首次被調用。
el 被新建立的 vm.$el 替換,並掛載到實例上去以後調用該鉤子。若是 root 實例掛載了一個文檔內元素,當 mounted 被調用時 vm.$el 也在文檔內。
tip: 1.在這個週期內,對data的改變能夠生效。可是要進下一輪的dom更新,dom上的數據纔會更新。 2.這個週期能夠獲取 dom。 以前的論斷有誤,感謝@馮銀超 和 @AnHour的提醒 3.beforeRouteEnter的next的勾子比mounted觸發還要靠後 4.指令的生效在mounted週期以前
數據更新時調用,發生在虛擬 DOM 從新渲染和打補丁以前。你能夠在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染過程。
因爲數據更改致使的虛擬 DOM 從新渲染和打補丁,在這以後會調用該鉤子。當這個鉤子被調用時,組件 DOM 已經更新,因此你如今能夠執行依賴於 DOM 的操做。然而在大多數狀況下,你應該避免在此期間更改狀態,由於這可能會致使更新無限循環。
實例銷燬以前調用。在這一步,實例仍然徹底可用。
tip: 1.這一步還能夠用this來獲取實例。 2.通常在這一步作一些重置的操做。好比清除掉組件中的 定時器 和 監聽的dom事件
Vue 實例銷燬後調用。調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。
做用於全部路由切換,通常在main.js裏面定義
示例 router.beforeEach((to, from, next) => { console.log('路由全局勾子:beforeEach -- 有next方法') next() })
通常在這個勾子的回調中,對路由進行攔截。
好比,未登陸的用戶,直接進入了須要登陸纔可見的頁面,那麼能夠用next(false)來攔截,使其跳回原頁面。
值得注意的是,若是沒有調用next方法,那麼頁面將卡在那。
next的四種用法 1.next() 跳入下一個頁面 2.next('/path') 改變路由的跳轉方向,使其跳到另外一個路由 3.next(false) 返回原來的頁面 4.next((vm)=>{}) 僅在beforeRouteEnter中可用,vm是組件實例。
示例 router.afterEach((to, from) => { console.log('路由全局勾子:afterEach --- 沒有next方法') })
在全部路由跳轉結束的時候調用,和beforeEach是相似的,可是它沒有next方法
和全局勾子不一樣的是,它僅僅做用於某個組件,通常在.vue文件中去定義。
示例 beforeRouteEnter (to, from, next) { console.log(this) //undefined,不能用this來獲取vue實例 console.log('組件路由勾子:beforeRouteEnter') next(vm => { console.log(vm) //vm爲vue的實例 console.log('組件路由勾子beforeRouteEnter的next') }) }
這個是一個很不一樣的勾子。由於beforeRouterEnter在組件建立以前調用,因此它沒法直接用this來訪問組件實例。
爲了彌補這一點,vue-router開發人員,給他的next方法加了特技,能夠傳一個回調,回調的第一個參數便是組件實例。
通常咱們能夠利用這點,對實例上的數據進行修改,調用實例上的方法。
咱們能夠在這個方法去請求數據,在數據獲取到以後,再調用next就能保證你進頁面的時候,數據已經獲取到了。沒錯,這裏next有阻塞的效果。你沒調用的話,就會一直卡在那
tip: next(vm=>{console.log('next') }) 這個裏面的代碼是很晚執行的,在組件mounted週期以後。沒錯,這是一個坑。你要注意。 beforeRouteEnter的代碼時很早執行的,在組件beforeCreate以前; 可是next裏面回調的執行,很晚,在mounted以後,能夠說是目前我找到的,離dom渲染最近的一個週期。
beforeRouteLeave (to, from, next) { console.log(this) //能夠訪問vue實例 console.log('組件路由勾子:beforeRouteLeave') next() },
在離開路由時調用。能夠用this來訪問組件實例。可是next中不能傳回調。
這個方法是vue-router2.2版本加上的。由於原來的版本中,若是一個在兩個子路由之間跳轉,是不觸發beforeRouteLeave的。這會致使某些重置操做,沒地方觸發。在以前,咱們都是用watch $route來hack的。可是經過這個勾子,咱們有了更好的方式。
老實講,我沒用過這個勾子,因此各位能夠查看一下文章以前的文檔,去嘗試一下,再和我交流交流。
綁定自定義指令的時候也會有對應的週期。
這幾個週期,我比較經常使用的,通常是隻有bind。
只調用一次,指令第一次綁定到元素時調用,用這個鉤子函數能夠定義一個在綁定時執行一次的初始化動做。
被綁定元素插入父節點時調用(父節點存在便可調用,沒必要存在於 document 中)。
其實是插入vnode的時候調用。
被綁定元素所在的模板更新時調用,而不論綁定值是否變化。經過比較更新先後的綁定值,能夠忽略沒必要要的模板更新。
慎用,若是在指令裏綁定事件,而且用這個週期的,記得把事件註銷
被綁定元素所在模板完成一次更新週期時調用。
只調用一次, 指令與元素解綁時調用。
示例: created () { this.$nextTick(() => { console.log('nextTick') //回調裏的函數一直到真實的dom渲染結束後,才執行 }) console.log('組件:created') },
nextTick方法的回調會在dom更新後再執行,所以能夠和一些dom操做搭配一塊兒用,如 ref。
很是好用,能夠解決不少疑難雜症。
場景: 你用ref得到一個輸入框,用v-model綁定。 在某個方法裏改變綁定的值,在這個方法裏用ref去獲取dom並取值,你會發現dom的值並無改變。 由於此時vue的方法,還沒去觸發dom的改變。 所以你能夠把獲取dom值的操做放在vm.$nextTick的回調裏,就能夠了。