快應用 生命周期

2020-08-08 15:22 更新

了解頁面的生命周期與狀態(tài),APP的生命周期

通過本節(jié),你將學會:

教程文檔對應的項目代碼文件:src/Lifecycle目錄,src/app.ux文件

生命周期圖


頁面的生命周期

由于頁面通過ViewModel渲染,那么頁面的生命周期指的也就是ViewModel的生命周期,包括常見的:onInit, onReady, onShow在頁面創(chuàng)建時觸發(fā)調用

onInit()

表示ViewModel的數據已經準備好,可以開始使用頁面中的數據,如下所示:

private: {

  // 生命周期的文本列表

  lcList: []

},

onInit () {

  this.$page.setTitleBar({ text: '生命周期' })

  this.lcList.push('onInit')

  console.info(`觸發(fā):onInit`)

  console.info(`執(zhí)行:獲取ViewModel的lcList屬性:${this.lcList}`)   // 執(zhí)行:獲取ViewModel的lcList屬性:onInit

  // $app信息

  console.info(`獲?。簃anifest.json的config.data的數據:${this.$app.$data.name}`)

  console.info(`獲取:APP文件中的數據:${this.$app.$def.data1.name}`)

  console.info(`執(zhí)行:APP文件中的方法`, this.$app.$def.method1())

}

onReady()

表示ViewModel的模板已經編譯完成,可以開始獲取 DOM 節(jié)點(如:this.$element(idxxx)),如下所示:

onReady () {
  this.lcList.push('onReady')

  console.info(`觸發(fā):onReady`)
  console.info(`執(zhí)行:獲取模板節(jié)點:${this.$rootElement()}`)   // 執(zhí)行:獲取模板節(jié)點:<div attr={} style={"flexDirection":"column"}>...</div>
}

onShow(), onHide()

APP中可以同時運行多個頁面,但是每次只能顯示其中一個頁面;這點不同與純前端開發(fā),瀏覽器頁面中每次只能有一個頁面,當前頁簽打開另一個頁面,上個頁面就銷毀了;不過和SPA開發(fā)倒有點相似,切換頁面但瀏覽器全局Context是共享的

所以頁面的切換,就產生了新的事件:頁面被切換隱藏時調用 onHide(),頁面被切換重新顯示時調用onShow()

判斷頁面的顯示狀態(tài),可以調用ViewModel$visible屬性:true表示顯示,false表示隱藏,示例如下:

onShow () {
  this.lcList.push('onShow')

  console.info(`觸發(fā):onShow`)
  console.info(`執(zhí)行:獲取頁面顯示狀態(tài)屬性:${this.$visible}`)  // true
}
onHide () {
  this.lcList.push('onHide')

  console.info(`觸發(fā):onHide`)
  console.info(`執(zhí)行:獲取頁面顯示狀態(tài)屬性:${this.$visible}`)  // false
}

onDestroy()

頁面被銷毀時調用,被銷毀的可能原因有:用戶從當前頁面返回到上一頁,或者用戶打開了太多的頁面,框架自動銷毀掉部分頁面,避免占用資源

所以,頁面銷毀時應該做一些釋放資源的操作,如:取消接口訂閱監(jiān)聽geolocation.susubscribe()

判斷頁面是否處于被銷毀狀態(tài),可以調用Viewmodel$valid屬性:true表示存在,false表示銷毀,示例如下:

onDestroy () {
  console.info(`觸發(fā):onDestroy`)
  console.info(`執(zhí)行:頁面要被銷毀,銷毀狀態(tài):${this.$valid},應該做取消接口訂閱監(jiān)聽的操作: geolocation.unsubscribe()`)    // true,即將銷毀
  setTimeout(function () {
    console.info(`執(zhí)行:頁面已被銷毀,不會執(zhí)行`)                                        // 頁面已銷毀,不會執(zhí)行
  }.bind(this), 0)
}

提示:

  1. onDestroy()中判斷$valid沒有意義,因為頁面即將被銷毀;如果在本頁面之外持有該Viewmodel的引用則可以通過$valid判斷頁面狀態(tài)
  2. setTimeout之類的異步操作綁定在了當前頁面上,因此當頁面銷毀之后異步調用不會執(zhí)行

onBackPress()

當用戶點擊返回實體按鍵、左上角返回菜單、調用返回API時觸發(fā)該事件

如果事件響應方法最后返回true表示不返回,自己處理業(yè)務邏輯(完畢后開發(fā)者自行調用API返回);否則:不返回數據,或者返回其它數據:表示遵循系統(tǒng)邏輯:返回到上一頁,示例如下:

onBackPress () {
  console.info(`觸發(fā):onBackPress`)
  // true:表示自己處理;否則默認返回上一頁
  // return true
}

    onMenuPress()

    menu_compare

    在 1070 以前的版本,當同時滿足當前頁面的manifest.json中的menu值為 true 與titleBar值為 true 時,此時屏幕頂部的標題欄會顯示右側的菜單按鈕,點擊此按鈕會觸發(fā)onMenuPress回調

    1070 版本開始,快應用推出了新的menuBar膠囊按鈕的交互形式,取代了之前標題欄右側菜單按鈕的按鈕交互。當manifest.json中的menu值為 true 時,點擊menuBar的左側按鈕,也會觸發(fā)onMenuPress回調,詳見menuBar 文檔

    注意: 若onMenuPress回調在當前頁面被實現了,且符合上述觸發(fā)onMenuPress回調的條件,點擊menumenubar系統(tǒng)彈窗邏輯就會被攔截不觸發(fā),示例如下:

    // 只要實現了此回調,就會攔截當前頁面的menu或menubar的系統(tǒng)彈窗邏輯

    onMenuPress(){

      prompt.showToast({

        message: `我攔截了menu點擊`

      })

    }

    onRefresh()

    監(jiān)聽頁面重新打開。詳細說明請參考文檔

    1.當頁面在 manifest 中 launchMode1050+ 標識為 'singleTask' 時,僅會存在一個目標頁面實例,用戶多次打開目標頁面時觸發(fā)此函數。

    2.打開目標頁面時在 push 參數中攜帶 flag 'clearTask',且頁面實例已經存在時觸發(fā)。該回調中參數為重新打開該頁面時攜帶的參數。詳見頁面啟動模式

    示例如下:

    onRefresh() {
      console.log('page refreshed!!!')
    }

    onConfigurationChanged(event)

    監(jiān)聽應用配置發(fā)生變化。當應用配置發(fā)生變化時觸發(fā),如系統(tǒng)語言或主題模式改變,詳細說明請參考文檔

    onConfigurationChanged(evt) {
      console.log(`觸發(fā)生命周期onConfigurationChanged, 配置類型:${evt.type}`)
    }

    頁面的狀態(tài)

    如上所述,APP中允許多個頁面同時存在并運行,但當前僅顯示其中一個,因此每個頁面就會處于多個狀態(tài)的一個狀態(tài)

    1. 顯示:該頁面就是當前APP正在顯示的頁面,用$visible判斷
    2. 隱藏:該頁面上打開新頁面后,該頁面被隱藏,用$visible判斷
    3. 銷毀:該頁面因某原因銷毀后,就不會再執(zhí)行里面的代碼,用$valid判斷

    關于接口調用與頁面的生命周期與狀態(tài),詳見文檔script 腳本

    APP的生命周期

    當前為 APP 的生命周期提供了七個回調函數:onCreate()、onRequest()、onShow()、onHide()、onDestroy()、onError()、onPageNotFound() ,可在app.ux中定義回調函數, 詳情及參數,示例如下:

    export default {

      onCreate() {

        console.info('Application onCreate')

      },

      onRequest() {

        console.info('Application onRequest')

      },

      onShow() {

        console.info('Application onShow')

      },

      onHide() {

        console.info('Application onHide')

      },

      onDestroy() {

        console.info('Application onDestroy')

      },

      onError() {

        console.log('Application onError')

      },

      onPageNotFound(params) {

        const { uri = '' } = params

        console.error('error uri', uri)

      },

      // 暴露給所有頁面,在頁面中通過:this.$app.$def.method1()訪問

      method1() {

        console.info('這是APP的方法')

      },

      // 暴露給所有頁面,在頁面中通過:this.$app.$def.data1訪問

      data1: {

        name: '這是APP存的數據'

      }

    }

    app.ux中,開發(fā)者可以做一些獨立于頁面的操作。比如:引入公共的JS資源,然后暴露給所有頁面

    app.ux中,通過this訪問app.ux中定義的數據和方法,示例如下:

    console.info(`獲取:APP文件中的數據:${this.$def.data1.name}`)
    console.info(`執(zhí)行:APP文件中的方法`, this.$def.method1())
    console.info(`獲取:manifest.json的應用名稱:${this.$def.manifest.name}`)
    console.info(`獲?。簃anifest.json的config.data的數據:${this.$data.name}`)

    pageName.ux中,通過this.$app訪問app.ux中定義的數據和方法,示例如下:

    console.info(`獲?。篈PP文件中的數據:${this.$app.$def.data1.name}`)
    console.info(`執(zhí)行:APP文件中的方法`, this.$app.$def.method1())
    console.info(`獲?。簃anifest.json的應用名稱:${this.$app.$def.manifest.name}`)
    console.info(`獲?。簃anifest.json的config.data的數據:${this.$app.$data.name}`)

    關于$app與$app.$def

    $app與$app.$def(后面簡稱$def)是兩個不同的對象;

    前者代表框架為開發(fā)者暴露提供的APP對象;后者代表開發(fā)者在app.ux中導出的對象,放置業(yè)務相關的全局數據和方法;

    初學開發(fā)者可以跳過該塊學習,待后期深入了解;

    前者對象擁有onCreate, onDestroy生命周期;當應用啟動時會執(zhí)行onCreate方法,里面執(zhí)行this.variable1的賦值是在$app對象上;

    后者對象中的onCreate, onDestroy方法并不會執(zhí)行,作用僅僅只是把方法復制到前者對象上而已;

    這些全局方法在頁面中:既可以通過this.$app.method1()調用,也可以通過this.$app.$def.method1()調用;不同之處在于前者可以取到之前賦值的variable1變量,而后者不可以取到(因為之前的賦值是在$app對象上執(zhí)行的);

    總結

    理解頁面與APP的生命周期,有助于更好的組織頁面的業(yè)務邏輯,方便頁面之間的交互與資源釋放等的處理


    以上內容是否對您有幫助:
    在線筆記
    App下載
    App下載

    掃描二維碼

    下載編程獅App

    公眾號
    微信公眾號

    編程獅公眾號