生命周期

了解页面的生命周期与状态,APP 的生命周期

通过本节,你将学会:

  • 页面的生命周期:onInitonReadyonShowonHideonDestroyonBackPressonMenuPress
  • 页面的状态:显示隐藏销毁
  • APP 的生命周期:onCreateonDestroy

生命周期图

生命周期图

页面的生命周期

由于页面通过ViewModel渲染,那么页面的生命周期指的也就是ViewModel的生命周期,包括常见的:onInit, onReady, onShow 在页面创建时触发调用

onInit()

表示ViewModel的数据已经准备好,可以开始使用页面中的数据

示例如下:

  1. private: {
  2. // 生命周期的文本列表
  3. lcList: []
  4. },
  5. onInit () {
  6. this.$page.setTitleBar({ text: '生命周期' })
  7. this.lcList.push('onInit')
  8. console.info(`触发:onInit`)
  9. console.info(`执行:获取ViewModel的lcList属性:${this.lcList}`) // 执行:获取ViewModel的lcList属性:onInit
  10. // $app信息
  11. console.info(`获取:manifest.json的config.data的数据:${this.$app.$data.name}`)
  12. console.info(`获取:APP文件中的数据:${this.$app.$def.data1.name}`)
  13. console.info(`执行:APP文件中的方法`, this.$app.$def.method1())
  14. }

onReady()

表示ViewModel的模板已经编译完成,可以开始获取 DOM 节点(如:this.$element(idxxx)

示例如下:

  1. onReady () {
  2. this.lcList.push('onReady')
  3. console.info(`触发:onReady`)
  4. console.info(`执行:获取模板节点:${this.$rootElement()}`) // 执行:获取模板节点:<div attr={} style={"flexDirection":"column"}>...</div>
  5. }

onShow(), onHide()

APP 中可以同时运行多个页面,但是每次只能显示其中一个页面;这点不同与纯前端开发,浏览器页面中每次只能有一个页面,当前页签打开另一个页面,上个页面就销毁了;不过和 SPA 开发倒有点相似,切换页面但浏览器全局 Context 是共享的

所以页面的切换,就产生了新的事件:页面被切换隐藏时调用 onHide(),页面被切换重新显示时调用 onShow()

判断页面的显示状态,可以调用ViewModel$visible属性:true表示显示,false表示隐藏

示例如下:

  1. onShow () {
  2. this.lcList.push('onShow')
  3. console.info(`触发:onShow`)
  4. console.info(`执行:获取页面显示状态属性:${this.$visible}`) // true
  5. },
  6. onHide () {
  7. this.lcList.push('onHide')
  8. console.info(`触发:onHide`)
  9. console.info(`执行:获取页面显示状态属性:${this.$visible}`) // false
  10. }

onDestroy()

页面被销毁时调用,被销毁的可能原因有:用户从当前页面返回到上一页,或者用户打开了太多的页面,框架自动销毁掉部分页面,避免占用资源

所以,页面销毁时应该做一些释放资源的操作,如:取消接口订阅监听geolocation.unsubscribe()

判断页面是否处于被销毁状态,可以调用ViewModel$valid属性:true表示存在,false表示销毁

示例如下:

  1. onDestroy () {
  2. console.info(`触发:onDestroy`)
  3. console.info(`执行:页面要被销毁,销毁状态:${this.$valid},应该做取消接口订阅监听的操作: geolocation.unsubscribe()`) // true,即将销毁
  4. setTimeout(function () {
  5. console.info(`执行:页面已被销毁,不会执行`) // 页面已销毁,不会执行
  6. }.bind(this), 0)
  7. }

提示:

  • onDestroy()中判断$valid没有意义,因为页面即将被销毁;如果在本页面之外持有该ViewModel的引用则可以通过$valid判断页面状态
  • setTimeout之类的异步操作绑定在了当前页面上,因此当页面销毁之后异步调用不会执行

onBackPress()

当用户点击返回实体按键左上角返回菜单调用返回API时触发该事件

如果事件响应方法最后返回true表示不返回,自己处理业务逻辑(完毕后开发者自行调用 API 返回);否则:不返回数据,或者返回其它数据:表示遵循系统逻辑:返回到上一页

示例如下:

  1. onBackPress () {
  2. console.info(`触发:onBackPress`)
  3. // true:表示自己处理;否则默认返回上一页
  4. // return true
  5. }

提示:

  • 返回上一页的接口 API:router.back(),详见文档页面路由

onMenuPress()

当使用原生的顶部标题栏时,可以通过manifest.json中的menu属性配置是否显示右上角的菜单,详见文档manifest 文件

示例如下:

  1. onMenuPress () {
  2. this.lcList.push('onMenuPress')
  3. console.info(`触发:onMenuPress`)
  4. }

页面的状态

如上所述,APP 中允许多个页面同时存在并运行,但当前仅显示其中一个,因此每个页面就会处于多个状态的一个状态

  • 显示:该页面就是当前 APP 正在显示的页面,用$visible判断
  • 隐藏:该页面上打开新页面后,该页面被隐藏,用$visible判断
  • 销毁:该页面因某原因销毁后,就不会再执行里面的代码,用$valid判断关于接口调用与页面的生命周期与状态,详见文档script 脚本

APP 的状态

当前为 APP 的生命周期提供了两个回调函数:onCreate, onDestroy;可在app.ux中定义回调函数

示例如下:

  1. import { natives } from './util/asyncNatives'
  2. export default {
  3. onCreate() {
  4. console.info('Application onCreate')
  5. },
  6. onDestroy() {
  7. console.info('Application onDestroy')
  8. },
  9. // 暴露给所有页面,在页面中通过:this.$app.$def.method1()访问
  10. method1() {
  11. console.info('这是APP的方法')
  12. },
  13. // 暴露给所有页面,在页面中通过:this.$app.$def.data1访问
  14. data1: {
  15. name: '这是APP存的数据'
  16. },
  17. natives
  18. }

app.ux中,开发者可以做一些独立于页面的操作。比如:引入公共的 JS 资源,然后暴露给所有页面

app.ux中,通过this.$def访问app.ux中定义的数据和方法

示例如下:

  1. console.info(`获取:APP文件中的数据:${this.$def.data1.name}`)
  2. console.info(`执行:APP文件中的方法`, this.$def.method1())
  3. console.info(`获取:manifest.json的应用名称:${this.$def.manifest.name}`)
  4. console.info(`获取:manifest.json的config.data的数据:${this.$data.name}`)

pageName.ux中,通过this.$app.$def访问app.ux中定义的数据和方法

示例如下:

  1. console.info(`获取:APP文件中的数据:${this.$app.$def.data1.name}`)
  2. console.info(`执行:APP文件中的方法`, this.$app.$def.method1())
  3. console.info(`获取:manifest.json的应用名称:${this.$app.$def.manifest.name}`)
  4. console.info(`获取:manifest.json的config.data的数据:${this.$app.$data.name}`)

关于$app 与$app.$def

$app 与$app.$def(后面简称$def)是两个不同的对象;

前者代表框架为开发者暴露提供的 APP 对象;后者代表开发者在 app.ux 中导出的对象,放置业务相关的全局数据和方法;

初学开发者可以跳过该块学习,待后期深入了解;

前者对象拥有 onCreate, onDestroy 生命周期;当应用启动时会执行 onCreate 方法,里面执行 this.variable1 的赋值是在$app 对象上;

后者对象中的 onCreate, onDestroy 方法并不会执行,作用仅仅只是把方法复制到前者对象上而已;

这些全局方法在页面中:既可以通过 this.$app.method1()调用,也可以通过 this.$app.$def.method1()调用;不同之处在于前者可以取到之前赋值的 variable1 变量,而后者不可以取到(因为之前的赋值是在$app 对象上执行的);

总结

理解页面与 APP 的生命周期,有助于更好的组织页面的业务逻辑,方便页面之间的交互与资源释放等的处理