vue生命週期探究(一)

vue官方文檔---實例生命週期
vue-router2.3版文檔---路由勾子
vue官方文檔---指令及其綁定週期html

前言

在使用vue開發的過程當中,咱們常常會接觸到生命週期的問題。那麼你知道,一個標準的工程項目中,會有多少個生命週期勾子嗎?讓咱們來一塊兒來盤點一下:vue

  1. 根組件實例:8個 (beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed)node

  2. 組件實例:8個 (beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed)ajax

  3. 全局路由鉤子:2個 (beforeEach、afterEach)vue-router

  4. 組件路由鉤子:3個 (beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave)segmentfault

  5. 指令的週期: 5個 (bind、inserted、update、componentUpdated、unbind)dom

  6. beforeRouteEnter的next所對應的週期ide

  7. nextTick所對應的週期函數

嚇到了嗎?合計居然一共有28個週期,是否看得頭昏眼花了呢?接下來讓咱們一塊兒來介紹一下各個週期的一般用途與使用細節吧ui

組件實例週期

這一塊vue2的官方文檔有一張圖示,咱們簡要提一下用法和注意

beforeCreate

在實例初始化以後,數據觀測(data observer) 和 event/watcher 事件配置以前被調用。

tip:

此時組件的選項還未掛載,所以沒法訪問methods,data,computed上的方法或數據

created

實例已經建立完成以後被調用。在這一步,實例已完成如下的配置:數據觀測(data observer),屬性和方法的運算, watch/event 事件回調。然而,掛載階段還沒開始,$el 屬性目前不可見。

這是一個經常使用的生命週期,由於你能夠調用methods中的方法、改變data中的數據,而且修改能夠經過vue的響應式綁定體如今頁面上、獲取computed中的計算屬性等等。

tip:

一般咱們能夠在這裏對實例進行預處理。
也有一些童鞋喜歡在這裏發ajax請求,值得注意的是,這個週期中是沒有什麼方法來對實例化過程進行攔截的。
所以假若有某些數據必須獲取才容許進入頁面的話,並不適合在這個頁面發請求。
建議在組件路由勾子beforeRouteEnter中來完成。

beforeMonut

在掛載開始以前被調用:相關的 render 函數首次被調用。

mounted

el 被新建立的 vm.$el 替換,並掛載到實例上去以後調用該鉤子。若是 root 實例掛載了一個文檔內元素,當 mounted 被調用時 vm.$el 也在文檔內。

tip:

1.在這個週期內,對data的改變能夠生效。可是要進下一輪的dom更新,dom上的數據纔會更新。
2.這個週期能夠獲取 dom。 以前的論斷有誤,感謝@馮銀超 和 @AnHour的提醒
3.beforeRouteEnter的next的勾子比mounted觸發還要靠後
4.指令的生效在mounted週期以前

beforeUpdate

數據更新時調用,發生在虛擬 DOM 從新渲染和打補丁以前。你能夠在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染過程。

updated

因爲數據更改致使的虛擬 DOM 從新渲染和打補丁,在這以後會調用該鉤子。當這個鉤子被調用時,組件 DOM 已經更新,因此你如今能夠執行依賴於 DOM 的操做。然而在大多數狀況下,你應該避免在此期間更改狀態,由於這可能會致使更新無限循環。

beforeDestroy

實例銷燬以前調用。在這一步,實例仍然徹底可用。

tip:

1.這一步還能夠用this來獲取實例。
2.通常在這一步作一些重置的操做。好比清除掉組件中的 定時器 和 監聽的dom事件

destroyed

Vue 實例銷燬後調用。調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。

全局路由鉤子

做用於全部路由切換,通常在main.js裏面定義

router.beforeEach

示例
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

示例
router.afterEach((to, from) => {
  console.log('路由全局勾子:afterEach --- 沒有next方法')
})

在全部路由跳轉結束的時候調用,和beforeEach是相似的,可是它沒有next方法

組件路由勾子

和全局勾子不一樣的是,它僅僅做用於某個組件,通常在.vue文件中去定義。

beforeRouteEnter

示例
  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

beforeRouteLeave (to, from, next) {
    console.log(this)    //能夠訪問vue實例
    console.log('組件路由勾子:beforeRouteLeave')
    next()
  },

在離開路由時調用。能夠用this來訪問組件實例。可是next中不能傳回調。

beforeRouteUpdate

這個方法是vue-router2.2版本加上的。由於原來的版本中,若是一個在兩個子路由之間跳轉,是不觸發beforeRouteLeave的。這會致使某些重置操做,沒地方觸發。在以前,咱們都是用watch $route來hack的。可是經過這個勾子,咱們有了更好的方式。

老實講,我沒用過這個勾子,因此各位能夠查看一下文章以前的文檔,去嘗試一下,再和我交流交流。

指令週期

綁定自定義指令的時候也會有對應的週期。
這幾個週期,我比較經常使用的,通常是隻有bind。

bind

只調用一次,指令第一次綁定到元素時調用,用這個鉤子函數能夠定義一個在綁定時執行一次的初始化動做。

inserted

被綁定元素插入父節點時調用(父節點存在便可調用,沒必要存在於 document 中)。
其實是插入vnode的時候調用。

update

被綁定元素所在的模板更新時調用,而不論綁定值是否變化。經過比較更新先後的綁定值,能夠忽略沒必要要的模板更新。
慎用,若是在指令裏綁定事件,而且用這個週期的,記得把事件註銷

componentUpdated

被綁定元素所在模板完成一次更新週期時調用。

unbind

只調用一次, 指令與元素解綁時調用。

Vue.nextTick、vm.$nextTick

示例:
  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的回調裏,就能夠了。

vue生命週期探究(二)

相關文章
相關標籤/搜索