【Vue】詳解Vue生命週期

 

(這裏的紅邊圓角矩形內的都是對應的Vue實例的鉤子函數)

在beforeCreate和created鉤子函數間的生命週期

 

在beforeCreate和created之間,進行數據觀測(data observer) ,也就是在這個時候開始監控data中的數據變化了,同時初始化事件
 

created鉤子函數和beforeMount間的生命週期

 

對於created鉤子函數和beforeMount間可能會讓人感到有些迷惑,下面我就來解釋一下:

el選項的有無對生命週期過程的影響

首先系統會判斷對象中有沒有el選項
有el選項,則繼續編譯過程
沒有el選項,則中止編譯,也意味着暫時中止了生命週期,直到vm.$mount(el)
下面我展現一下:
複製代碼
new Vue({
  el: '#app',
  beforeCreate: function () {
    console.log('調用了beforeCreat鉤子函數')
  },
  created: function () {
    console.log('調用了created鉤子函數')
  },
  beforeMount: function () {
    console.log('調用了beforeMount鉤子函數')
  },
  mounted: function () {
    console.log('調用了mounted鉤子函數')
  }
})
複製代碼

 

demo以下:

 

能夠看到,在el選項填寫且正確的時候,生命週期將正常進行
 
而當咱們把el去掉:
複製代碼
new Vue({
  beforeCreate: function () {
    console.log('調用了beforeCreat鉤子函數')
  },
  created: function () {
    console.log('調用了created鉤子函數')
  },
  beforeMount: function () {
    console.log('調用了beforeMount鉤子函數')
  },
  mounted: function () {
    console.log('調用了mounted鉤子函數')
  }
})
複製代碼

 

demo:
 

 

能夠看到,生命週期的鉤子函數 執行到created就結束了
而當咱們不加el選項, 可是手動執行vm.$mount(el)方法的話,也可以使暫停的生命週期進行下去,例如:
複製代碼
var vm = new Vue({
  beforeCreate: function () {
    console.log('調用了beforeCreat鉤子函數')
  },
  created: function () {
    console.log('調用了created鉤子函數')
  },
  beforeMount: function () {
    console.log('調用了beforeMount鉤子函數')
  },
  mounted: function () {
    console.log('調用了mounted鉤子函數')
  }
})
vm.$mount('#app')
複製代碼

 

demo以下,能夠看到,這個時候雖然對象中沒有el參數,但經過$mount(el)動態添加的方式,也可以使生命週期順利進行
 

 

template參數選項的有無對生命週期的影響

 

 

1.若是Vue實例對象中有template參數選項,則將其做爲模板編譯成render函數
2.若是沒有template參數選項,則將外部的HTML做爲模板編譯(template),也就是說,template參數選項的優先級要比外部的HTML高
3.若是1,2條件都不具有,則報錯
 
咱們能夠把模板寫在template參數選項中:
new Vue({
  el: '#app',
  template: '<div id="app"><p>模板在templated參數中找到了喲~</p></div>'
})
demo:

 

 

 

也能夠把參數選項寫在外部HTML中,像這樣:
 
外部HTML:
<div id="app"><p>模板是在外部HTML中找到的~</p></div>
建立對象實例:
new Vue({
  el: '#app'
})

 

demo:

 

那麼有趣的問題來了,當模板同時放在template參數選項和外部HTML中,會怎樣呢?
例如:
外部HTML:
<div id="app"><p>模板是在外部HTML中找到的~</p></div>

 

 
建立Vue實例(包含template參數選項)
new Vue({
  el: '#app',
  template: '<div id="app"><p>模板在templated參數中找到了喲~</p></div>'
})

 

demo以下:

 

很顯然,正如我上面下的結論同樣,最終顯示的是「模板在templated參數中找到了喲~」而不是「模板是在外部HTML中找到的~」,由於template參數的優先級比外部HTML的優先級要高
 
【注意】
1.爲何判斷el要發生在判斷template前面呢
 
由於Vue須要經過el的「選擇器」找到對應的template。總結一下上述的過程,Vue經過el參數去找到對應的template。而後,根據el參數給出的「選擇器」,首先去Vue實例對象自己的template選項參數中找,若是沒有template參數,則到外部HTML中尋找,找到後將模板編譯成render函數
 
2.實際上,在Vue中,有render函數這個選項,它以createElement做爲參數,作渲染操做。固然你也能夠不調用createElement,而直接嵌入JSX(學習react的同窗對此應該很熟悉吧)。
複製代碼
new Vue({
  el: '#demo',
  render (createElement) {
    return (....)
  }
})
複製代碼

 

【注意】render選項參數比template更接近Vue解析器!因此綜合排列以下:
render函數選項  > template參數  > 外部HTML
 

Vue的編譯過程——把模板編譯成 render 函數

Vue的編譯其實是指Vue把模板編譯成 render 函數的過程
 
咱們能夠經過Vue.compile這個實時編譯模板的函數來看一看:
用官方文檔的例子作個解釋:
複製代碼
<div>
  <header>
    <h1>I'm a template!</h1>
  </header>
  <p v-if="message">
    {{ message }}
  </p>
  <p v-else>
    No message.
  </p>
</div>
複製代碼

 

  
會被渲染成
function anonymous() {
  with(this){return _c('div',[_m(0),(message)?_c('p',[_v(_s(message))]):_c('p',[_v("No message.")])])}
}

 

beforeMount和mounted鉤子函數間的生命週期

 

 

對於這一點, 我也感到有些迷惑,百度後以後也沒什麼頭緒,最後我思考的結果是這樣的:正由於render函數和template選項的「優先級」比外部HTML要高,因此,最後通常會存在一個外部HTML模板被Vue實例自己配置的模板所「替代」的過程也就是上圖所說的 「replace」
 
(若是你們有不一樣意見也能夠在評論處一塊兒討論)
 

beforeUpdate鉤子函數和updated鉤子函數間的生命週期

 

 

在Vue中,數據更改會致使虛擬 DOM 從新渲染,並前後調用beforeUpdate鉤子函數和updated鉤子函數
 
但要注意一點: 重渲染(調用這兩個鉤子函數)的前提是被更改的數據已經被寫入模板中!!(這點很重要)
例如:
複製代碼
var vm = new Vue({
  el: '#app',
  data: {
    number: 1
  },
  template: '<div id="app"><p></p></div>',
  beforeUpdate: function () {
    console.log('調用了beforeUpdate鉤子函數')
  },
  updated: function () {
    console.log('調用了updated鉤子函數')
  }
})
 
vm.number = 2
複製代碼

 

 

 

控制檯上並無如咱們預料那樣輸出調用兩個鉤子函數的文本
而當咱們改爲
複製代碼
var vm = new Vue({
  el: '#app',
  data: {
    number: 1
  },
  // 在模板中使用number這個數據
  template: '<div id="app"><p>  {{ number }} </p></div>',
  beforeUpdate: function () {
    console.log('調用了beforeUpdate鉤子函數')
  },
  updated: function () {
    console.log('調用了updated鉤子函數')
  }
})
 
vm.number = 2
 
複製代碼

 

 

 
這個時候,調用兩個鉤子函數的文本就被輸出來了
總之,只有Vue實例中的數據被「寫入」到咱們的模板中,它的改變才能夠被Vue追蹤,重渲染從而調用 beforeUpdate鉤子函數和updated鉤子函數
 

beforeDestroy和destroyed鉤子函數間的生命週期

 

 

beforeDestroy鉤子函數在實例銷燬以前調用。在這一步,實例仍然徹底可用。
 
destroyed鉤子函數在Vue 實例銷燬後調用。調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。
 
【注意】就如同調用在Vue實例上調用$mounted會使暫停的生命週期繼續同樣,調用$destroy()會直接銷燬實例
相關文章
相關標籤/搜索