[WeexTips]合理使用Weex的生命週期
這是 Weex Tips 系列文章中的一篇,彙總目錄在 這裡。
- 首先建議先看一下有關元件定義的官方文件,其中介紹了生命週期。
- 在 Weex 專案裡有個 issue 專門描述了 Weex 的生命週期,裡面有幾張很清晰的圖,我這裡只講一下用法。
- 如果想了解元件的編譯細節可以參考:《詳解 Weex JS Framework 的編譯過程》。
如果看完了上邊的連結,對 Weex 生命週期的理解應該很到位了,可以簡單總結成這麼一張圖:
注:在新版本的 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>
注意這幾個生命週期函式 init
、created
、ready
、destroyed
和 data
、methods
屬性是平級的,不要將其放在 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
方法。
此時可以通過 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 開發組的同學討論解決方法。
相關文章
- View生命週期與Activity生命週期的關係View
- 生命週期
- Flutter 的生命週期Flutter
- SQL的生命週期SQL
- Laravel的生命週期Laravel
- vue的生命週期Vue
- Fragment的生命週期Fragment
- App的生命週期APP
- View的生命週期View
- Servlet的生命週期Servlet
- bean的生命週期Bean
- 非同步載入在Vue生命週期哪個階段更合理非同步Vue
- PHP 生命週期PHP
- Flutter - 生命週期Flutter
- sessionStorag 生命週期Session
- Fragment生命週期Fragment
- Activity生命週期
- vue - 生命週期Vue
- React生命週期React
- ubuntu生命週期Ubuntu
- React 生命週期React
- vue生命週期Vue
- 品牌生命週期和產品生命週期之間的關係
- vue使用總結-生命週期篇Vue
- [譯]如何使用React生命週期方法React
- Salesforce 生命週期管理(一)應用生命週期淺談Salesforce
- React新的生命週期React
- iOS APP的生命週期iOSAPP
- Java 物件的生命週期Java物件
- Vue生命週期的理解Vue
- [React]元件的生命週期React元件
- Avalonia的Window生命週期
- Vue的生命週期的理解Vue
- Activity生命週期onDestroy
- Flutter -- Element生命週期Flutter
- java servlet 生命週期JavaServlet
- React-生命週期React
- vue 生命週期梳理Vue