正文
在上一期中我们了解到, 用于构造页面的 Component 构造器可以同时使用组件和页面的生命周期属性, 那么, 这些生命周期之间的顺序是怎样的呢? 我们需要的自定义 tabbar 又是在哪一周期被加入到页面中的呢? 更进一步, 当我们使用多种拥有生命周期的对象时, 它们之间的顺序是如何的呢?
拥有生命周期的对象-基础
我们首先分析微信小程序中常见的拥有生命周期的对象
Page
| 属性 | 类型 | 说明 |
|---|---|---|
onLoad | function | 生命周期回调—监听页面加载 |
onShow | function | 生命周期回调—监听页面显示 |
onReady | function | 生命周期回调—监听页面初次渲染完成 |
onHide | function | 生命周期回调—监听页面隐藏 |
onUnload | function | 生命周期回调—监听页面卸载 |
列出 Page 对象的生命周期后不由得让人产生疑问: 这些没有时态的英语单词到底表示的是什么时刻呢? 例如: onHide 是页面即将隐藏时触发还是页面隐藏后触发?(此处的页面指的是用户看到的页面)
我们可以在官方文档中找到讲解页面生命周期的图示,:
从图中可以看出:
- 在初次加载时, 逻辑层在结束
create进入created后, 会连续触发onLoad,onShow两个生命周期, 然后会将初始数据发送给渲染层, 渲染层在接受到数据后进行首次渲染, 渲染结束后用户可以看到页面. 因此我认为:onLoad生命周期可以看作是页面加载前触发, 且只触发一次 - 对于
onShow生命周期, 我们看逻辑层图示下方的深色Alive(后台状态)和浅色Alive(前台状态)的切换过程更好理解. 从图中可以看出, 在后台状态时, 逻辑层接收到set to foreground信号, 此时onShow生命周期立即触发, 注意,onShow生命周期结束后逻辑层才从后台状态进入前台状态. 因此我认为:onshow生命周期可以看作是页面显示前触发, 可触发多次 onHide生命周期可以和onshow生命周期对称理解, 即onHide生命周期可以看作是页面隐藏前触发, 可触发多次- 对于
onReady生命周期, 可以看出它是在渲染层完成初次渲染后触发的, 即onReady生命周期可以看作是页面初次渲染完成后触发, 且只触发一次 - 对于
onUnload生命周期, 可以看出它是在逻辑层接收到destroy信号后触发, 完成后渲染层和逻辑层生命周期同时结束, 即onUnload生命周期可以看作是页面卸载前触发, 且只触发一次
上述 Page 的生命周期可总结为下图:
Component
-
组件本身生命周期
生命周期 描述 created在组件实例创建完成后执行(给组件 this添加一些自定义属性字段)attached在组件实例进入页面节点树后执行(进行初始化) ready在组件在视图层布局完成后执行 moved在组件实例被移动到节点树另一个位置时执行 detached在组件实例被从页面节点树移除时执行 -
组件所在页面的生命周期
生命周期 描述 show组件所在的页面被展示前执行 hide组件所在的页面被隐藏前执行 resize组件所在的页面尺寸变化时执行
此处的组件我们专指从属于页面内部的组件, 由于属于页面内部的组件与页面关系密切, 因此, 我们主要需要了解页面内部的组件生命周期和页面生命周期之间的关系
-
初次载入
从上图可以看出:
- 页面内部组件的
created生命周期先于attached生命周期触发, 但二者都是在页面的onLoad生命周期之前触发, 均仅触发一次 - 页面内部组件的
show生命周期先于页面onShow生命周期, 可触发多次 - 页面内部组件的
ready生命周期先于页面onReady生命周期, 仅触发一次
- 页面内部组件的
-
路由切换
从上图可以看出:
- 页面内部组件的
hide生命周期先于页面onHide生命周期, 可触发多次 - 页面内部组件的
show生命周期先于页面onShow生命周期, 可触发多次
- 页面内部组件的
-
页面卸载
从上图可以看出: 页面内部组件的
detached生命周期后于页面onUnload生命周期, 且仅触发一次
页面内部组件的生命周期和 Page 的生命周期可总结为下图:
自定义 tabbar
自定义 tabbar 使用的是组件的生命周期, 但在实际实验中却发现了非常有趣的现象
-
载入
APP首页从上图红框中的
WebViewId可以看出: 载入整个APP首页时, 不仅会最先加载本页自定义tabbar, 而且会提前加载下页的自定义tabbar -
路由至非首页
从上图红框可以看出: 在上一页提前加载好的自定义
tabbar的WebViewId和本页的WebViewId对应, 而且在本页也会提前加载下页的自定义tabbar
上述发现在微信小程序官方的问答中得到验证
在 2.6.2+ ,我们会尝试提前为下一个页面创建一个 tabBar 实例,以便打开下一个页面能更快显示出 tabBar ,所以你会看到一个 tabBar 实例被创建,并且它的 WebviewId 是新的,过了很久之后页面才被创建出来。
但是我在测试自定义 tabbar 栏的过程中发现三个问题:
-
自定义
tabbar栏的show和hide生命周期不会被触发?对于这个问题我的想法是:
tabbar和Page是并列关系而非从属关系, 如下图所示:在调试器的
Wxml部分可以看出:page标签和tab-bar标签是处于同一层级的, 而show和hide生命周期是根据组件所在页面来进行触发的, 这里的所在页面的含义我想指的就是在page标签内部, 而tab-bar和page标签平级, 自然就不会触发了
但剩下两个我没能找到合理的解释, 已经反馈给微信社区, 但是目前并没有人回应...
如果大家这两个问题有想法的话, 希望能多多分享:)
基于上述实验结果总结而来的自定义 tabbar, 页面内部组件和 Page 的生命周期顺序如下图:
-
APP首页 -
非首页
测试源代码
developers.weixin.qq.com/s/N6ziPbm57…
大家可以自己进行上述测试, 如果存在什么问题, 希望可以多多指教:)
预告
Component 构造器构造页面
在本期中, 我们介绍了微信小程序中较为常见的拥有生命周期的对象, 以及在组合使用时, 它们各自生命周期的顺序. 但微信小程序还提供了其它更为进阶的拥有生命周期的对象, 例如在微信小程序提供的自定义 tabbar 样例中使用到的 Component 构造器构造页面等...
对于这些对象, 我们将在下期进行分析:)