Vue.js (8) - Vue 實體與生命週期

Vue.js

看了那麼多使用 Vue 的範例,最後我們來看看 Vue 實體以及它從建立到銷毀的整個生命週期,以便對 Vue 有更完整的瞭解。

建構式

在 Vue.js 中,所有的應用程式都必須使用 Vue() 建構式來建立 Vue 實體:
JavaScriptvar vm = new Vue({
  //選項
})
在實體化 Vue 時,需要傳入一個選項(Options)物件,它包含了所有 Vue 實體需要用到的屬性,選項物件的屬性有很多,使用時只要填寫我們需要用到的屬性即可。這些屬性包含前幾章都介紹過的掛載元素(el)、資料(data)、方法(methods)、模板(template)、生命週期掛鉤等等,全部的選項可以在 API 文件中查看。

實體的屬性與方法

每個 Vue 實體都會代理其 data 物件裡所有的屬性,也就是我們可以從 Vue 實體直接取用 data 物件的屬性:
JavaScriptvar vm = new Vue({
  data: {
    a: 1
  }
})
// 從實體取 data 物件的屬性
console.log(vm.a) // 1
這裡要注意的是,由於 JavaScript 的特性允許我們直接在實體上加上新屬性,但對 Vue 來說,這種在實體被建立之後加入的新屬性,是沒有自動響應的功能,請看範例:
HTML<div id="vm">
  {{ a }} <!-- 這裡會顯示 1 -->
  {{ b }} <!-- 這裡什麼都沒有 -->
</div>

<script>
var vm = new Vue({
  el: '#vm',
  data: {
    a: 1
  }
})
// 在實體建立後加上新屬性 b
vm.b = 2

console.log(vm.a) // 1
console.log(vm.b) // 2
</script>
實際上這麼做是沒意義的,所以請不要這麼做。

在 Vue 實體被建立後,如果有需要存取其中的屬性或方法,Vue.js 也提供了取用它們的功能,這些允許被存取的屬性與方法都以 $ 開頭,用來區分 Vue 實體所代理的屬性與方法。
使用範例:
HTML<div id="vm">
  {{ a }}
</div>

<script>
var vm = new Vue({
  el: '#vm',
  data: {
    a: 1
  }
})

// 取得 el 屬性, 和用 JavaScript 方法取得的元素比對
console.log(vm.$el === document.querySelector('#vm')) // true

// 取得資料物件的屬性
console.log(vm.a)

// 呼叫 watch 方法,當 a 的值改變時觸發
vm.$watch('a', function(newVal, oldVal){
  console.log('a 現在是 ' + newVal + ', 之前是' + oldVal)
  // a 現在是 2, 之前是1
})
// 模擬 2 秒後改變 a 的值,會觸發 vm.$watch() 方法
setTimeout(function(){
  vm.a = 2
}, 2000)
</script>


實體生命週期

每個 Vue 實體被創建之前,會經過一系列初始化的過程,同時會呼叫這些生命週期的掛鉤,我們可以在這些掛鉤上做額外的處理。

全部的生命週期掛鉤依序如下 (請參照清單下的圖):
  1. beforeCreate:實體初始化。
  2. Created:實體建立完成。資料 $data 已可取得,但 $el 屬性還未被建立。
  3. beforeMount:執行元素掛載之前。
  4. mounted:元素已掛載, $el 被建立。
  5. beforeUpdate:當資料變化時被呼叫,還不會描繪 View。
  6. updated:DOM 的更新已經完成,View 被顯示在畫面上。
  7. activated:如果有設定 keep-alive,這個掛鉤會被呼叫。
  8. deactivated:停用 keep-alive時被呼叫。
  9. beforeDestroy:實體還可使用。
  10. destroyed:實體銷毀。所有綁定被解除、事件偵聽被移除、子實體也被銷毀。
註:它們的資料型態全都是 Functionvue-lifecycle (圖片來源:https://cn.vuejs.org/v2/guide/instance.html)

如果要對 DOM 做動作,記得要在 mounted 掛鉤中,它如同 onload 事件,或是 jQuery 中的 ready(),示範如下:
HTMLvar vm = new Vue({
  el: '#vm',
  data: {
    a: 1
  },
  beforeCreate: function(){
    console.log('== beforeCreate ==')
    console.log('this.a: ' + this.a)
    console.log('this.$el: ' + this.$el)
    console.log()
  },
  created: function(){
    console.log('== created ==')
    console.log('this.a: ' + this.a)
    console.log('this.$el: ' + this.$el)
    console.log()
  },
  mounted: function(){
    console.log('== mounted ==')
    console.log('this.a: ' + this.a)
    console.log('this.$el: ' + this.$el)
  }
})
Console 顯示結果:
Output== beforeCreate ==
this.a: undefined
this.$el: undefined

== created ==
this.a: 1
this.$el: undefined

== mounted ==
this.a: 1
this.$el: [object HTMLDivElement]
你會看到,在 beforeCreate 時,資料和元素掛載都還沒被建立;created 時,資料已經可以取得了,但元素掛載還沒;mounted 時,全部都被建立了,如果你想改變 DOM 或資料,可以在這裡做,因為它還沒被瀏覽器「畫」出來,必須直到 updated 執行時,才會把最終的結果畫在瀏覽器上被看到。

有些時候你會需要在 Vue 實體的生命週期中做一些事情,瞭解它們的運作方式可以幫助你在對的階段中做事。
本文網址:https://blog.tonycube.com/2017/04/vuejs-8-lifecycle.html
Tony Blog 撰寫,請勿全文複製,轉載時請註明出處及連結,謝謝 😀

我要留言

留言小提醒:
1.回覆時間通常在晚上,如果太忙可能要等幾天。
2.請先瀏覽一下其他人的留言,也許有人問過同樣的問題。
3.程式碼請先將它編碼後再貼上。(線上編碼:http://bit.ly/1DL6yog)
4.文字請加上標點符號及斷行,難以閱讀者恕難回覆。
5.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。