【小程序】生命周期
【查看原文】
小程序分為應用、頁面和組件三個部分,所以小程序的生命周期涉及以下:
- 應用的生命周期
- 頁面的生命周期
- 組件的聲明周期
- 應用的生命周期對頁面生命周期的影響
(1)應用的生命周期
App()
函數用來註冊一個小程序。接受一個 Object
參數,其指定小程序的生命周期回調等。App()
必須在 app.js
中調用,必須調用且只能調用一次。
App({
onLaunch: function(options) {
// 監聽小程序初始化。小程序初始化完成時(全局只觸發一次)
},
onShow: function(options) {
// 監聽小程序顯示。小程序啟動,或從後臺進入前臺顯示時
},
onHide: function() {
// 監聽小程序隱藏。小程序從前臺進入後臺時。
},
onError: function(msg) {
console.log(msg) // 錯誤監聽函數。小程序發生腳本錯誤,或者 api 調用失敗時觸發,會帶上錯誤信息
},
onPageNotFound: function(res) {
// 頁面不存在監聽函數。小程序要打開的頁面不存在時觸發,會帶上頁面信息回調該函數
},
globalData: ‘I am global data‘
})
前臺、後臺定義: 當用戶點擊左上角關閉,或者按了設備 Home 鍵離開微信,小程序並沒有直接銷毀,而是進入了後臺;當再次進入微信或再次打開小程序,又會從後臺進入前臺。
我們來看圖:應用生命周期
- 用戶首次打開小程序,觸發 onLaunch 方法(全局只觸發一次)。
- 小程序初始化完成後,觸發 onShow 方法,監聽小程序顯示。
- 小程序從前臺進入後臺,觸發 onHide 方法。
- 小程序從後臺進入前臺顯示,觸發 onShow 方法。
- 小程序後臺運行一定時間,或系統資源占用過高,會被銷毀。
全局的 getApp()
函數可以用來獲取到小程序 App
實例。
// other.js
var appInstance = getApp()
console.log(appInstance.globalData) // I am global data
註意:
- 不要在定義於 App() 內的函數中調用 getApp() ,使用 this 就可以拿到 app 實例。
- 通過 getApp() 獲取實例之後,不要私自調用生命周期函數。
(2)頁面的生命周期
Page(Object)
函數用來註冊一個頁面。接受一個 Object
類型參數,其指定頁面的初始數據、生命周期回調、事件處理函數等。
//index.js
Page({
data: {
// 頁面的初始數據
text: "This is page data."
},
onLoad: function(options) {
// 生命周期回調—監聽頁面加載
},
onReady: function() {
// 生命周期回調—監聽頁面初次渲染完成
},
onShow: function() {
// 生命周期回調—監聽頁面顯示
},
onHide: function() {
// 生命周期回調—監聽頁面隱藏
},
onUnload: function() {
// 生命周期回調—監聽頁面卸載
},
onPullDownRefresh: function() {
// 監聽用戶下拉動作
},
onReachBottom: function() {
// 頁面上拉觸底事件的處理函數
},
onShareAppMessage: function () {
// 用戶點擊右上角轉發
},
onPageScroll: function() {
// 頁面滾動觸發事件的處理函數
},
onResize: function() {
// 頁面尺寸改變時觸發
},
onTabItemTap(item) {
// 當前是 tab 頁時,點擊 tab 時觸發
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
},
// 任意的函數,在頁面的函數中用 this 可以訪問
viewTap: function() {
this.setData({
text: ‘Set some data for updating view.‘
}, function() {
// this is setData callback
})
},
// 任意數據,在頁面的函數中用 this 可以訪問
customData: {
hi: ‘MINA‘
}
})
我們來看圖:頁面生命周期
- 小程序註冊完成後,加載頁面,觸發onLoad方法。
- 頁面載入後觸發onShow方法,顯示頁面。
- 首次顯示頁面,會觸發onReady方法,渲染頁面元素和樣式,一個頁面只會調用一次。
- 當小程序後臺運行或跳轉到其他頁面時,觸發onHide方法。
- 當小程序有後臺進入到前臺運行或重新進入頁面時,觸發onShow方法。
- 當使用重定向方法wx.redirectTo(object)或關閉當前頁返回上一頁wx.navigateBack(),觸發onUnload。
總結
onLoad
: 頁面加載。一個頁面只會調用一次。參數可以獲取wx.navigateTo
和wx.redirectTo
及<navigator/>
中的query
。onShow
: 頁面顯示。每次打開頁面都會調用一次。onReady
: 頁面初次渲染完成。一個頁面只會調用一次,代表頁面已經準備妥當,可以和視圖層進行交互。對界面的設置如wx.setNavigationBarTitle
請在onReady
之後設置。onHide
: 頁面隱藏。當navigateTo
或底部tab
切換時調用。onUnload
: 頁面卸載。當redirectTo
或navigateBack
的時候調用。
Page 實例的生命周期
我們來看圖:實例生命周期
小程序由兩大線程組成:負責界面的視圖線程(view thread)和負責數據、服務處理的服務線程(appservice thread),兩者協同工作,完成小程序頁面生命周期的調用。
視圖線程有四大狀態:
- 初始化狀態:初始化視圖線程所需要的工作,初始化完成後向 “服務線程”發送初始化完成信號,然後進入等待狀態,等待服務線程提供初始化數據。
- 首次渲染狀態:當收到服務線程提供的初始化數據後(json和js中的data數據),渲染小程序界面,渲染完畢後,發送“首次渲染完成信號”給服務線程,並將頁面展示給用戶。
- 持續渲染狀態:此時界面線程繼續一直等待“服務線程”通過this.setdata()函數發送來的界面數據,只要收到就重新局部渲染,也因此只要更新數據並發送信號,界面就自動更新。
- 結束狀態:頁面被回收或者銷毀、應用被系統回收、銷毀時觸發。
服務線程五大狀態:
- 初始化狀態:此階段僅啟動服務線程所需的基本功能,比如信號發送模塊。系統的初始化工作完畢,就調用自定義的onload和onshow,然後等待視圖線程的“初始化完成”。onload是只會首次渲染的時候執行一次,onshow是每次界面切換都會執行。
- 等待激活狀態:接收到“視圖線程初始化完成”信號後,將初始化數據發送給“視圖線程”,等待視圖線程完成初次渲染。
- 激活狀態:收到視圖線程發送來的“首次渲染完成”信號後,就進入激活狀態既程序的正常運行狀態,並調用自定義的onReady()函數。此狀態下就可以通過 this.setData 函數發送界面數據給界面線程進行局部渲染,更新頁面。
- 後臺運行狀態:如果界面進入後臺,服務線程就進入後臺運行狀態,從目前的官方解讀來說,這個狀態挺奇怪的,和激活狀態是相同的,也可以通過setdata函數更新界面的。畢竟小程序的框架剛推出,應該後續會有很大不同吧。
- 結束狀態:頁面被回收或者銷毀、應用被系統回收、銷毀時觸發。
另: 寫過react的童鞋都知道,react 中使用了 will、 did、should 等一系列有時態語義的詞匯命名鉤子函數。小程序中,統一使用on,那麽on是在行為前還是行為後,從實例生命周期圖中,我們可以明顯看到:鉤子觸發執行時機都是在事件完成之後觸發的。例如
set to background
之後onHode
。
(3) 組件的生命周期
組件的生命周期,指的是組件自身的一些函數,這些函數在特殊的時間點或遇到一些特殊的框架事件時被自動觸發。
其中,最重要的生命周期是 created attached detached ,包含一個組件實例生命流程的最主要時間點。
- created 組件實例化,但節點樹還未導入,因此這時不能用setData
- attached 組件初始化完畢,節點樹完成,可以用setData渲染節點,但無法操作節點
- ready 組件布局完成,這時可以獲取節點信息,也可以操作節點
- moved 組件實例被移動到樹的另一個位置
- detached 組件實例從節點樹中移
組件所在頁面的生命周期, 指的是那些並非與組件有很強的關聯,但有時組件需要獲知,以便組件內部處理的生命周期,在 pageLifetimes 定義段中定義。
- show 組件所在的頁面被展示時執行
- hide 組件所在的頁面被隱藏時執行
- resize 組件所在的頁面尺寸變化時執行
Component({
lifetimes: {
created() {
// 在組件實例剛剛被創建時執行
},
attached() {
// 在組件實例進入頁面節點樹時執行
},
ready() {
// 在組件在視圖層布局完成後執行
},
moved() {
// 在組件實例被移動到節點樹另一個位置時執行
},
detached() {
// 在組件實例被從頁面節點樹移除時執行
},
error(err) {
// 每當組件方法拋出錯誤時執行
}
},
pageLifetimes: {
show() {
// 頁面被展示
},
hide() {
// 頁面被隱藏
},
resize(size) {
// 頁面尺寸變化
}
},
// 以下是舊式的定義方式,可以保持對 <2.2.3 版本基礎庫的兼容
attached() {
// 在組件實例進入頁面節點樹時執行
},
detached() {
// 在組件實例被從頁面節點樹移除時執行
},
// ...
})
(4)應用的生命周期對頁面生命周期的影響
我們來看圖:應用生命周期影響頁面生命周期
- 小程序初始化完成後,頁面首次加載觸發onLoad,只會觸發一次。
- 當小程序進入到後臺,先執行頁面onHide方法再執行應用onHide方法。
- 當小程序從後臺進入到前臺,先執行應用onShow方法再執行頁面onShow方法。
app onLaunch
app onShow
component created
component attached
page onLoad {id: "test"}
component show
page onShow
component ready
page onReady
page onUnload
component detached
app onHide
參考文檔
- 玩轉Page組件的生命周期
- 微信小程序之生命周期(四)
- 微信小程序之生命周期(三)
【小程序】生命周期