1. 程式人生 > >【小程序】生命周期

【小程序】生命周期

子函數 str for 展示 pat 正常 -a eno share

【查看原文】

小程序分為應用、頁面和組件三個部分,所以小程序的生命周期涉及以下:

  • 應用的生命周期
  • 頁面的生命周期
  • 組件的聲明周期
  • 應用的生命周期對頁面生命周期的影響

(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 鍵離開微信,小程序並沒有直接銷毀,而是進入了後臺;當再次進入微信或再次打開小程序,又會從後臺進入前臺。

我們來看圖:應用生命周期

技術分享圖片

  1. 用戶首次打開小程序,觸發 onLaunch 方法(全局只觸發一次)。
  2. 小程序初始化完成後,觸發 onShow 方法,監聽小程序顯示。
  3. 小程序從前臺進入後臺,觸發 onHide 方法。
  4. 小程序從後臺進入前臺顯示,觸發 onShow 方法。
  5. 小程序後臺運行一定時間,或系統資源占用過高,會被銷毀。

全局的 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.navigateTowx.redirectTo<navigator/>中的 query
  • onShow: 頁面顯示。每次打開頁面都會調用一次。
  • onReady: 頁面初次渲染完成。一個頁面只會調用一次,代表頁面已經準備妥當,可以和視圖層進行交互。對界面的設置如wx.setNavigationBarTitle請在onReady之後設置。
  • onHide: 頁面隱藏。當navigateTo或底部tab切換時調用。
  • onUnload: 頁面卸載。當redirectTonavigateBack的時候調用。

Page 實例的生命周期

我們來看圖:實例生命周期

技術分享圖片

小程序由兩大線程組成:負責界面的視圖線程(view thread)和負責數據、服務處理的服務線程(appservice thread),兩者協同工作,完成小程序頁面生命周期的調用。

視圖線程有四大狀態:

  1. 初始化狀態:初始化視圖線程所需要的工作,初始化完成後向 “服務線程”發送初始化完成信號,然後進入等待狀態,等待服務線程提供初始化數據。
  2. 首次渲染狀態:當收到服務線程提供的初始化數據後(json和js中的data數據),渲染小程序界面,渲染完畢後,發送“首次渲染完成信號”給服務線程,並將頁面展示給用戶。
  3. 持續渲染狀態:此時界面線程繼續一直等待“服務線程”通過this.setdata()函數發送來的界面數據,只要收到就重新局部渲染,也因此只要更新數據並發送信號,界面就自動更新。
  4. 結束狀態:頁面被回收或者銷毀、應用被系統回收、銷毀時觸發。

服務線程五大狀態:

  1. 初始化狀態:此階段僅啟動服務線程所需的基本功能,比如信號發送模塊。系統的初始化工作完畢,就調用自定義的onload和onshow,然後等待視圖線程的“初始化完成”。onload是只會首次渲染的時候執行一次,onshow是每次界面切換都會執行。
  2. 等待激活狀態:接收到“視圖線程初始化完成”信號後,將初始化數據發送給“視圖線程”,等待視圖線程完成初次渲染。
  3. 激活狀態:收到視圖線程發送來的“首次渲染完成”信號後,就進入激活狀態既程序的正常運行狀態,並調用自定義的onReady()函數。此狀態下就可以通過 this.setData 函數發送界面數據給界面線程進行局部渲染,更新頁面。
  4. 後臺運行狀態:如果界面進入後臺,服務線程就進入後臺運行狀態,從目前的官方解讀來說,這個狀態挺奇怪的,和激活狀態是相同的,也可以通過setdata函數更新界面的。畢竟小程序的框架剛推出,應該後續會有很大不同吧。
  5. 結束狀態:頁面被回收或者銷毀、應用被系統回收、銷毀時觸發。

另: 寫過react的童鞋都知道,react 中使用了 will、 did、should 等一系列有時態語義的詞匯命名鉤子函數。小程序中,統一使用on,那麽on是在行為前還是行為後,從實例生命周期圖中,我們可以明顯看到:鉤子觸發執行時機都是在事件完成之後觸發的。例如 set to background 之後 onHode



(3) 組件的生命周期

組件的生命周期,指的是組件自身的一些函數,這些函數在特殊的時間點或遇到一些特殊的框架事件時被自動觸發。

其中,最重要的生命周期是 created attached detached ,包含一個組件實例生命流程的最主要時間點。

  1. created 組件實例化,但節點樹還未導入,因此這時不能用setData
  2. attached 組件初始化完畢,節點樹完成,可以用setData渲染節點,但無法操作節點
  3. ready 組件布局完成,這時可以獲取節點信息,也可以操作節點
  4. moved 組件實例被移動到樹的另一個位置
  5. detached 組件實例從節點樹中移

組件所在頁面的生命周期, 指的是那些並非與組件有很強的關聯,但有時組件需要獲知,以便組件內部處理的生命周期,在 pageLifetimes 定義段中定義。

  1. show 組件所在的頁面被展示時執行
  2. hide 組件所在的頁面被隱藏時執行
  3. resize 組件所在的頁面尺寸變化時執行
Component({
  lifetimes: {
    created() {
      // 在組件實例剛剛被創建時執行
    },
    attached() {
      // 在組件實例進入頁面節點樹時執行
    },
    ready() {
      // 在組件在視圖層布局完成後執行
    },
    moved() {
      // 	在組件實例被移動到節點樹另一個位置時執行
    },
    detached() {
      // 在組件實例被從頁面節點樹移除時執行
    },
    error(err) {
      // 每當組件方法拋出錯誤時執行
    }
  },

  pageLifetimes: {
    show() {
      // 頁面被展示
    },
    hide() {
      // 頁面被隱藏
    },
    resize(size) {
      // 頁面尺寸變化
    }
  },

  // 以下是舊式的定義方式,可以保持對 <2.2.3 版本基礎庫的兼容
  attached() {
    // 在組件實例進入頁面節點樹時執行
  },
  detached() {
    // 在組件實例被從頁面節點樹移除時執行
  },
  // ...
})



(4)應用的生命周期對頁面生命周期的影響

我們來看圖:應用生命周期影響頁面生命周期

技術分享圖片

  1. 小程序初始化完成後,頁面首次加載觸發onLoad,只會觸發一次。
  2. 當小程序進入到後臺,先執行頁面onHide方法再執行應用onHide方法。
  3. 當小程序從後臺進入到前臺,先執行應用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組件的生命周期
  • 微信小程序之生命周期(四)
  • 微信小程序之生命周期(三)

【小程序】生命周期