[WeexTips]合理使用Weex的生命週期

門柳發表於2016-09-01

這是 Weex Tips 系列文章中的一篇,彙總目錄在 這裡

  • 首先建議先看一下有關元件定義的官方文件,其中介紹了生命週期。
  • 在 Weex 專案裡有個 issue 專門描述了 Weex 的生命週期,裡面有幾張很清晰的圖,我這裡只講一下用法。
  • 如果想了解元件的編譯細節可以參考:《詳解 Weex JS Framework 的編譯過程》

如果看完了上邊的連結,對 Weex 生命週期的理解應該很到位了,可以簡單總結成這麼一張圖:

Weex Lifecircle

注:在新版本的 JS Framework(>0.15.6)中才支援 destroyed 生命週期。

生命週期的用法

<script>
  module.exports = {
    data: {},
    methods: {},

    init: function () {
      console.log(`在初始化內部變數,並且新增了事件功能後被觸發`);
    },
    created: function () {
      console.log(`完成資料繫結之後,模板編譯之前被觸發`);
    },
    ready: function () {
      console.log(`模板已經編譯並且生成了 Virtual DOM 之後被觸發`);
    },
    destroyed: function () {
      console.log(`在頁面被銷燬時呼叫`);
    }
  }
</script>

注意這幾個生命週期函式 initcreatedreadydestroyeddatamethods 屬性是平級的,不要將其放在 methods 中,雖然當前版本相容這種用法,以後也有可能會放棄支援。

除此之外,不建議在根物件上定義其他屬性,資料應該放在 data 屬性中,自定義的方法放在 methods 中,方法的執行環境(this)是當前元件對應的 Vm 物件,介面參考:Instance Apis

init

init 方法執行時,剛初始化了內部變數,新增了事件的功能。此時還沒有執行資料繫結,也沒有建立 Virtual-DOM ,所以不能通過 this 獲取到 data 中的資料,不能呼叫到 methods 中定義的方法,也不能獲取到 Virtual-DOM 的節點。

可以在這個方法中可以初始化一些內部變數,也可以繫結一些自定義的事件。

created

created 的名稱有點令人迷惑,會讓人以為節點全部都建立完成了,其實只是剛完成了資料繫結,還沒開始編譯模板。此時可以通過 this 操作 data 中的資料,也可以呼叫 methods 中的方法,但是獲取不到 Virtual-DOM 的節點。

由於還沒開始執行節點的渲染,可以在 created 方法中修改 data 中的資料(例如某些需要動態計算的屬性),此時的修改不會觸發額外的渲染。

ready

ready 開始執行時,表示當前元件已經渲染完成。這個過程是自底向上觸發的,會首先先執行子元件的 ready 方法。也就是說,在父元件執行 ready 時,所有子元件都已經渲染完成,而且已經執行完各自的 ready 方法。

Weex Multi-component Lifecircle

此時可以通過 this.$el(id) 獲取到節點的 Virtual-DOM,也可以通過 this.$vm(id) 獲取到子元件的 Vm 例項。

不過,在 ready 方法中要小心地操作 data 中的資料,避免頻繁賦值,因為此時已經完成了資料和 UI 的繫結,每次修改值都可能觸發區域性頁面重新渲染。建議先取出需要頻繁改動的值,然後等操作執行結束後,再一併賦值:

module.exports = {
  data: {
    count: 0
  },
  ready: function () {
    var count = this.count;
    for (var i = 0; i < 999; i++) {
      count += Math.random();
    }
    this.count = count;
  }
}

如程式碼所示,在修改 this.count 前先獲取它的值,在執行完操作後再賦值回去,如果在迴圈體中直接設定 this.count 的值,頁面將觸發 999 次區域性重新整理,很可能會導致頁面卡頓。

對於複雜的資料物件,也建議用 取值 -> 修改 -> 賦值 的方式更新資料。

destroyed

destroyed 方法將在元件銷燬(通常是頁面跳轉)時被呼叫。和 ready 類似,它也是自底向上執行,先觸發子元件的 destroyed 方法,再觸發自身。而且框架會先執行開發者定義的 destroyed 方法,然後再清除內部屬性。

如果新增了一些屬性到全域性或者 this 上,建議在 destroyed 方法中手動清除,避免記憶體洩漏。

其他建議

無論在何時,都不建議獲取 Vm 和 Virtual-DOM 內部屬性,這部分資料對開發者是透明的,而且在版本迭代過程中很可能會修改。

如果有特殊開發需求,建議聯絡 Weex 開發組的同學討論解決方法。


相關文章