微信小程式詳解——小程式的生命週期和頁面的生命週期
我是一名安卓程式設計師,我們安卓中最明顯的特徵就是類具有生命週期。所以當開發小程式的時候,我自然而然的會先研究小程式的生命週期。在Android中是通過Application來管理安卓程式的生命週期,小程式中是通過App.js來管理小程式的生命週期。在Android頁面Activity和Fragment都是擁有生命週期的,同樣小程式的頁面Pager也擁有自己的生命週期。
1.小程式的生命週期——App.js
App() 必須在 app.js 中註冊,且不能註冊多個。所以App()方法在一個小程式中有且僅有一個。
App() 函式用來註冊一個小程式。接受一個 object 引數,其指定小程式的生命週期函式等。先上程式碼:
App({
onLaunch: function () {
console.log('App onLaunch');
},
onShow:function (){
console.log('App onShow');
},
onHide:function(){
console.log('App onHide');
},
onError:function(){
console.log('App onError');
},
getPics: function() {
return this .globalData.picList;
},
globalData:{
picList: [] // 圖片列表
},
globalName: 'tangdekun'
});
最外層的整個{ }就是一個object 引數。
通過表格的形式看App()中的object引數說明:
屬性 | 型別 | 描述 | 觸發時機 |
---|---|---|---|
onLaunch | Function | 生命週期函式–監聽小程式初始化 | 當小程式初始化完成時,會觸發 onLaunch(全域性只觸發一次)。 |
onShow | Function | 生命週期函式–監聽小程式顯示 | 當小程式啟動,或從後臺進入前臺顯示,會觸發 onShow |
onHide | Function | 生命週期函式–監聽小程式隱藏 | 當小程式從前臺進入後臺,會觸發 onHide |
onError | Function | 錯誤監聽函式 | 當小程式發生指令碼錯誤,或者 api 呼叫失敗時,會觸發 onError 並帶上錯誤資訊 |
其他 | Any | 開發者可以新增任意的函式或資料到 Object 引數中,用 this 可以訪問,上面的getPics就是函式, globalName是資料,這裡面的函式和資料都是全域性的。呼叫方式:在Pager中通過getApp()方法得到App物件並獲得全域性的資料和呼叫全域性的函式 |
將原有的app.js中替換為上面的程式碼,首次開啟小程式,可以在Log資訊中看到以下Log資訊,會看到onShow()方法會執行兩次
- App onLaunch
- App onShow()
- App onShow()
前臺、後臺定義: 當用戶點選左上角關閉,或者按了裝置 Home 鍵離開微信,小程式並沒有直接銷燬,而是進入了後臺;當再次進入微信或再次開啟小程式,又會從後臺進入前臺。
只有當小程式進入後臺一定時間,或者系統資源佔用過高,才會被真正的銷燬。
注意:
1.不要在定義於 App()
內的函式中呼叫 getApp()
,使用 this
就可以拿到 app
例項。
2.不要在 onLaunch
的時候呼叫 getCurrentPage()
,此時 page 還沒有生成。
3.通過 getApp()
獲取例項之後,不要私自呼叫生命週期函式。
2.頁面的生命週期
Page() 函式用來註冊一個頁面。接受一個 object 引數,其指定頁面的初始資料、生命週期函式、事件處理函式等。
生命週期函式
onLoad: 頁面載入
一個頁面只會呼叫一次。
接收頁面引數 可以獲取wx.navigateTo和wx.redirectTo及<navigator/>中的 query。
onShow: 頁面顯示
每次開啟頁面都會呼叫一次。
onReady: 頁面初次渲染完成
一個頁面只會呼叫一次,代表頁面已經準備妥當,可以和檢視層進行互動。
onHide: 頁面隱藏
當navigateTo或底部tab切換時呼叫。
onUnload: 頁面解除安裝
當redirectTo或navigateBack的時候呼叫。
其中APP的生命週期和頁面的生命週期是相互交叉的:舉例:
我們有頁面Test和Test1,我們在test.js,test1.js和App.js的生命週期方法中都列印log,程式碼如下:
test1.js
Page({
data:{
names:"tangdekun test1"
},
onLoad:function(options){
// 生命週期函式--監聽頁面載入
console.log("test1 onLoad");
},
onReady:function(){
// 生命週期函式--監聽頁面初次渲染完成
console.log("test1 onReady");
},
onShow:function(){
// 生命週期函式--監聽頁面顯示
console.log("test1 onShow");
},
onHide:function(){
// 生命週期函式--監聽頁面隱藏
console.log("test1 onHide");
},
onUnload:function(){
// 生命週期函式--監聽頁面解除安裝
console.log("test1 onUnload");
},
onPullDownRefresh: function() {
// 頁面相關事件處理函式--監聽使用者下拉動作
console.log("test1 onPullDownRefresh");
},
onReachBottom: function() {
// 頁面上拉觸底事件的處理函式
console.log("test1 onReachBottom");
}
})
test.js
Page({
data:{
name:"test"
},
onLoad:function(options){
// 生命週期函式--監聽頁面載入
console.log("test onLoad");
},
onReady:function(){
// 生命週期函式--監聽頁面初次渲染完成
console.log("test onReady");
},
onShow:function(){
// 生命週期函式--監聽頁面顯示
console.log("test onShow");
},
onHide:function(){
// 生命週期函式--監聽頁面隱藏
console.log("test onHide");
},
onUnload:function(){
// 生命週期函式--監聽頁面解除安裝
console.log("test onUnload");
},
onPullDownRefresh: function() {
// 頁面相關事件處理函式--監聽使用者下拉動作
console.log("test onPullDownRefresh");
},
onReachBottom: function() {
// 頁面上拉觸底事件的處理函式
console.log("test onReachBottom");
},
onShareAppMessage: function() {
// 使用者點選右上角分享
return {
title: '分享頁面', // 分享標題
desc: '這是一個分享的測試', // 分享描述
path: 'pages/waimai/waimai' // 分享路徑
}
},
navigateToPageB: function() {
wx.navigateTo({
url: '../../pages/pageB/pageB?id=3',
success: function(res){
},
fail: function() {
// fail
},
complete: function() {
// complete
}
})
},
redirectToPageA : function(){
wx.redirectTo({
url: '../../pages/pageA/pageA?id=4',
success: function(res){
// success
},
fail: function() {
// fail
},
complete: function() {
// complete
}
})
},
switchTabToTest1:function(){
wx.switchTab({
url: '../../pages/test1/test1',
success: function(res){
// success
},
fail: function() {
// fail
},
complete: function() {
// complete
}
})
}
})
app.js
//app.js
App({
onLaunch: function () {
console.log('App onLaunch');
},
onShow:function (){
console.log('App onShow1'+this.globalName);
},
onHide:function(){
console.log('App onHide');
},
onError:function(){
console.log('App onError');
},
getPics: function() {
return this.globalData.picList;
},
globalData:{
picList: [] // 圖片列表
},
globalName: 'tangdekun'
});
我們將test頁面設定為首頁【在app.json中設定】,程式會自動載入test頁面,呼叫test.js中的生命週期方法,列印Log資訊如下:
然後點選選單欄【作業中心】test1,會呼叫test 的onHide,test1的onLoad,onShow,onReady,列印Log資訊如下:
在點選【朋友圈】test,會呼叫test1的onHide方法,test的onshow方法,而不會呼叫test的onLoad,onReady方法,log資訊如下:
通過例項我們一起理解一下官方的小程式頁面的生命週期:
View thread是我們的wxml檔案,AppServiceThread就是我們js檔案中研究的頁面的生命週期。這裡我們可以看到每個生命週期方法的呼叫順序以及和Wxml之間的資訊交流。大家可以簡略的看一下就好。
因為頁面的生命週期和頁面的路由【即頁面之間的跳轉方式】有關,所以接下來我會向大家展示頁面跳轉的三種方式和各種跳轉方式之下的生命週期方法的排程。
為了方便大家一起交流學習,我和幾位資深小程式開發愛好者一起建了一個QQ交流群:481428150