浅析微信小程序组件所在页面的生命周期、uni-app如何使用小程序组件pageLifetimes的生命周期函数及onHide/onUnload不触发的原因
开发中经常会有这样的场景,我们自定义的组件需要在页面生命周期时做一些事情,像 Vue 这种组件开发时就很方便,但是微信小程序这种就分页面生命周期和组件生命周期,开发并不是那么方便了,所以需要了解一下。
一、微信小程序的组件生命周期
1、最重要的生命周期是 created
attached
detached。
- 组件实例刚刚被创建好时,
created
生命周期被触发。此时,组件数据this.data
就是在Component
构造器中定义的数据data
。 此时还不能调用setData
。 通常情况下,这个生命周期只应该用于给组件this
添加一些自定义属性字段。 - 在组件完全初始化完毕、进入页面节点树后,
attached
生命周期被触发。此时,this.data
已被初始化为组件的当前值。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。 - 在组件离开页面节点树后,
detached
生命周期被触发。退出一个页面时,如果组件还在页面节点树中,则detached
会被触发。
2、定义组件生命周期的方法
组件的生命周期可以在 lifetimes
字段内进行声明(这是推荐的方式,其优先级最高)
Component({
lifetimes: {
attached: function() {
// 在组件实例进入页面节点树时执行
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
},
},
// 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
attached: function() {
// 在组件实例进入页面节点树时执行
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
},
})
3、组件所在页面的生命周期
还有一些特殊的生命周期,它们并非与组件有很强的关联,但有时组件需要获知,以便组件内部处理。这样的生命周期称为“组件所在页面的生命周期”,在 pageLifetimes
定义段中定义。其中可用的生命周期包括:
Component({
pageLifetimes: {
show: function() {
// 组件所在的页面被展示时执行
},
hide: function() {
// 组件所在的页面被隐藏时执行
},
resize: function(size) {
// 组件所在的页面尺寸变化时执行
}
}
})
二、uni-app如何使用小程序组件Components里pageLifetimes下面的生命周期函数
如上节所述,小程序在自定义的组件里能够通过设置 pageLifetimes 监听父页面的生命周期函数,那么在uni-app中应该怎么做?
uni-app 开发小程序的话,直接 onPageShow、onPageHide、onPageResize 就可以。分别对应小程序组件里 pageLifetimes 的 show、hide、resize。
但是我在加了 onPageHide 后发现却怎么也触发不了,然后在页面加了 onHide 发现也触发不了,为什么?继续往下看。
三、uni-app 的 onHide 不触发
后来了解到说:uniapp开发微信小程序,隐藏当前页面时(跳转,销毁,隐藏)并不触发onHide事件,而是 触发unLoad事件。
因为uniapp开发小程序中,并不隐藏页面,而是直接销毁了,因此 触发unLoad事件 。因此业务逻辑应该写在 unLoad 中。
也就是说:页面销毁后就没有 onHide了,请使用 onUnload。
我个人觉得以上说法肯定也不对。如果页面都是销毁的话,那返回的时候岂不是都得重新渲染,而不是缓存,显然不是这样的。那么我就用项目中的试一试。
1、如下面这样 tabbar 之间导航页切换时,触发的是 onUnload,未触发 onHide
2、但是当 tabbar 导航页不变,如只是点击 “特色服务” 里的子页面时,触发的是:先触发的组件的 onPageHide,再触发页面的 onHide,不会触发“特色服务”页面的 onUnload
3、从子页面,再返回“特色服务”页面,触发的是:先触发的组件的 onPageShow,再触发的页面的 onShow
因为这个是项目里封装了的,tabbar 点击之间是用的 replace,所以相当于是之前的页面销毁,所以总结一下就是:
(1)页面有销毁,就是触发的 onUnload
(2)页面没销毁,就是触发的 onHide
(3)页面都销毁了,组件自然也销毁了,所以只有页面 onHide 的时候,组件才可能触发 onPageHide 事件。