菜鸟读文档-Vant Weapp-5(小程序中的生命周期-基础)

627 阅读7分钟

正文

在上一期中我们了解到, 用于构造页面的 Component 构造器可以同时使用组件和页面的生命周期属性, 那么, 这些生命周期之间的顺序是怎样的呢? 我们需要的自定义 tabbar 又是在哪一周期被加入到页面中的呢? 更进一步, 当我们使用多种拥有生命周期的对象时, 它们之间的顺序是如何的呢?

拥有生命周期的对象-基础

我们首先分析微信小程序中常见的拥有生命周期的对象

Page

属性类型说明
onLoadfunction生命周期回调—监听页面加载
onShowfunction生命周期回调—监听页面显示
onReadyfunction生命周期回调—监听页面初次渲染完成
onHidefunction生命周期回调—监听页面隐藏
onUnloadfunction生命周期回调—监听页面卸载

列出 Page 对象的生命周期后不由得让人产生疑问: 这些没有时态的英语单词到底表示的是什么时刻呢? 例如: onHide 是页面即将隐藏时触发还是页面隐藏后触发?(此处的页面指的是用户看到的页面)

我们可以在官方文档中找到讲解页面生命周期的图示,:

从图中可以看出:

  1. 在初次加载时, 逻辑层在结束 create 进入 created 后, 会连续触发 onLoad, onShow 两个生命周期, 然后会将初始数据发送给渲染层, 渲染层在接受到数据后进行首次渲染, 渲染结束后用户可以看到页面. 因此我认为: onLoad 生命周期可以看作是页面加载前触发, 且只触发一次
  2. 对于 onShow 生命周期, 我们看逻辑层图示下方的深色 Alive (后台状态)和浅色 Alive (前台状态)的切换过程更好理解. 从图中可以看出, 在后台状态时, 逻辑层接收到 set to foreground 信号, 此时 onShow 生命周期立即触发, 注意, onShow 生命周期结束后逻辑层才从后台状态进入前台状态. 因此我认为: onshow 生命周期可以看作是页面显示前触发, 可触发多次
  3. onHide 生命周期可以和 onshow 生命周期对称理解, 即 onHide 生命周期可以看作是页面隐藏前触发, 可触发多次
  4. 对于 onReady 生命周期, 可以看出它是在渲染层完成初次渲染后触发的, 即 onReady 生命周期可以看作是页面初次渲染完成后触发, 且只触发一次
  5. 对于 onUnload 生命周期, 可以看出它是在逻辑层接收到 destroy 信号后触发, 完成后渲染层和逻辑层生命周期同时结束, 即 onUnload 生命周期可以看作是页面卸载前触发, 且只触发一次

上述 Page 的生命周期可总结为下图:

Component

  • 组件本身生命周期

    生命周期描述
    created在组件实例创建完成后执行(给组件 this 添加一些自定义属性字段)
    attached在组件实例进入页面节点树后执行(进行初始化)
    ready在组件在视图层布局完成后执行
    moved在组件实例被移动到节点树另一个位置时执行
    detached在组件实例被从页面节点树移除时执行
  • 组件所在页面的生命周期

    生命周期描述
    show组件所在的页面被展示前执行
    hide组件所在的页面被隐藏前执行
    resize组件所在的页面尺寸变化时执行

此处的组件我们专指从属于页面内部的组件, 由于属于页面内部的组件与页面关系密切, 因此, 我们主要需要了解页面内部的组件生命周期和页面生命周期之间的关系

  • 初次载入

    从上图可以看出:

    1. 页面内部组件的 created 生命周期先于 attached 生命周期触发, 但二者都是在页面的 onLoad 生命周期之前触发, 均仅触发一次
    2. 页面内部组件的 show 生命周期先于页面 onShow 生命周期, 可触发多次
    3. 页面内部组件的 ready 生命周期先于页面 onReady 生命周期, 仅触发一次
  • 路由切换

    从上图可以看出:

    1. 页面内部组件的 hide 生命周期先于页面 onHide 生命周期, 可触发多次
    2. 页面内部组件的 show 生命周期先于页面 onShow 生命周期, 可触发多次
  • 页面卸载

    从上图可以看出: 页面内部组件的 detached 生命周期后于页面 onUnload 生命周期, 且仅触发一次

页面内部组件的生命周期和 Page 的生命周期可总结为下图:

自定义 tabbar

自定义 tabbar 使用的是组件的生命周期, 但在实际实验中却发现了非常有趣的现象

  • 载入 APP 首页

    从上图红框中的 WebViewId 可以看出: 载入整个 APP 首页时, 不仅会最先加载本页自定义 tabbar, 而且会提前加载下页的自定义 tabbar

  • 路由至非首页

    从上图红框可以看出: 在上一页提前加载好的自定义 tabbarWebViewId 和本页的 WebViewId 对应, 而且在本页也会提前加载下页的自定义 tabbar

上述发现在微信小程序官方的问答中得到验证

在 2.6.2+ ,我们会尝试提前为下一个页面创建一个 tabBar 实例,以便打开下一个页面能更快显示出 tabBar ,所以你会看到一个 tabBar 实例被创建,并且它的 WebviewId 是新的,过了很久之后页面才被创建出来。

但是我在测试自定义 tabbar 栏的过程中发现三个问题:

  1. 自定义 tabbar 栏的 showhide 生命周期不会被触发?

    对于这个问题我的想法是: tabbarPage 是并列关系而非从属关系, 如下图所示:

    在调试器的 Wxml 部分可以看出: page 标签和 tab-bar 标签是处于同一层级的, 而 showhide 生命周期是根据组件所在页面来进行触发的, 这里的所在页面的含义我想指的就是在 page 标签内部, 而 tab-barpage 标签平级, 自然就不会触发了

但剩下两个我没能找到合理的解释, 已经反馈给微信社区, 但是目前并没有人回应...

  1. 提前创建的 tabbar 的 WebViewId 与页面的 WebViewId 不匹配
  2. 自定义 tabbar 栏的 detached 生命周期不会触发?

如果大家这两个问题有想法的话, 希望能多多分享:)

基于上述实验结果总结而来的自定义 tabbar, 页面内部组件和 Page 的生命周期顺序如下图:

  • APP 首页

  • 非首页

测试源代码

developers.weixin.qq.com/s/N6ziPbm57…

大家可以自己进行上述测试, 如果存在什么问题, 希望可以多多指教:)

预告

Component 构造器构造页面

在本期中, 我们介绍了微信小程序中较为常见的拥有生命周期的对象, 以及在组合使用时, 它们各自生命周期的顺序. 但微信小程序还提供了其它更为进阶的拥有生命周期的对象, 例如在微信小程序提供的自定义 tabbar 样例中使用到的 Component 构造器构造页面等...

对于这些对象, 我们将在下期进行分析:)

菜鸟读文档-Vant Weapp-6(小程序中的生命周期-进阶)