生命周期
在微搭应用中,存在 应用(app)、页面(page)、组件(component)三种等级的实例,级别由高到低,应用包含 0-n 个页面,页面包含 0-n 个组件。通过实例生命周期钩子,可在实例不同阶段插入自定义代码。
生命周期钩子
应用(app)
hook | 说明 |
---|---|
onAppLaunch(Object:{query:Record<string, string>}) | 应用初始化时触发,全局只触发一次。参数为包含 query(应用启动参数)的对象 |
onAppShow(Object:{query:Record<string, string>}) | 应用启动或从后台进入前台显示(小程序)时触发 |
页面(page)
hook | 说明 |
---|---|
onPageLoad(query:Record<string, string>) | 页面加载时触发,一个页面只调用一次,参数 query 为打开当前页面时的参数对象 |
onPageShow() | 页面显示/切入嵌前台(小程序)时触发 |
onPageHide() | 页面隐藏/切入后台(小程序)时触发 ,如跳转到其他页(小程序特指 redirectTo,relunch,navigateBack 等销毁页面栈的动作),或小程序切入后台 |
onPageUnload() | 页面卸载时触发,如:跳转到其他页面时,当前页 unload。 |
组件(comp)
组件可能有多种自定义实现,仅列出最基础常见的声明周期钩子
hook | 说明 |
---|---|
onAttached() | 组件实例进入页面节点树时执行,对应 react willMount 生命周期 |
onReady() | 组件布局完成后执行,ownerComponent attached 触发后,其子组件,由深到浅,由前至后(先根遍历 DFS),触发 ready |
onDetached() | 在组件实例被从页面节点树移除时执行 |
调度
微搭在基础的实例声明周期外,还存在一些系统行为,涵盖同步、异步多种:
- 全局/页面级别变量初始化,包括同步初始化参数变量 & 异步创建并初始化模型变量 & 初始化自动触发类型的数据查询
- 默认登录,初始化用户数据
- 应用页面鉴权
ps: 在应用、页面生命周期前存在系统内置的调度阶段,下为方便说明,定义两阶段分别为
beforeCustomLaunch
&beforePageCustomLaunch
此外自定义方法中海可通过微搭 API 调用数据方法,方法为异步,需要请求服务器时,都会被阻塞在登录后进行。
试想当前存在应用,结构伪代码类似:
<app>
<page>
<container1><text1 /></container1>
<container2 />
</page>
</app>
则解析调度逻辑如下:
进入
beforeCustomLaunch
阶段,在所有同步/异步流程完成之前,都不会进行下一步,同时该阶段内部失败,会直接跳到下一步,不会阻断流程:- 解析应用参数,创建应用参数对象。
- 发起静默异步登录,不阻塞渲染和声明周期,特殊的 oauth 登录是进行阻塞,意味着当异步登录时,app 的
onAppLaunch
与onAppShow
等生命周期内不一定可以稳定的获取当前登录用户。 - 创建全局模型变量 & 异步调用数据源接口进行数据初始化(可选)。
- 初始化全局自动触发类型的数据查询,该初始化步骤为异步操作,不阻塞任何流程。
并发触发
onAppLaunch
与onAppShow
,由于 js 单进程模型,若两方法为同步方法,则最终效果类似串行执行。当方法为异步时,根据协程实现,两方法不会互相阻塞,且不阻塞后续流程。创建
$page
页面实例,进入页面生命周期挂载页面容器与样式进入
beforePageCustomLaunch
阶段,阻塞 page 其他生命周期:- 解析页面参数,创建参数对象
$w.page.dataset.state.params
- 页面鉴权,校验登录配置,当且仅当 登录完成 & 拥有页面权限时,开始渲染页面内容,因为登录已经完成,此后的流程都可以稳定的获取到
$w.auth.currentUser
。 - 初始化页面内自动触发类型的数据查询,该初始化步骤为异步操作,不阻塞任何流程。
- 解析页面参数,创建参数对象
由于鉴权后进行页面渲染,组件开始挂载,container1,text1,container2 (先根遍历 DFS)依次
onAttached
。挂载同时并发触发
onPageLoad
,onPageShow
,调度同 app 类似生命周期。page 实例 didmount 触发 container1,text1,container2 依次
onReady
。page 触发
onPageReady
页面销毁离开时,
onPageHide
,onPageUnload
触发,并非阻塞触发 container1,text1,container2 依次onDetached
。
小程序 App/Page
应用和页面生命周期 lifecycle 文件导出的生命周期方法会合并到微信小程序中分别对应其应用和页面的初始化参数中:
通过定义页面或者应用的小程序生命周期钩子可以实现和定制小程序特定的相关功能。比如:
- 在微搭应用 lifecycle 中添加
onThemeChange
,微搭会将其转换成 App 的参数 - 想在微搭中实现小程序分享等逻辑的话可以在页面生命周期中添加
onShareAppMessage
。具体用法参考: onShareTimeline,onShareAppMessage
ps: 由于小程序分享朋友圈限制单页未登录模式,微搭小程序暂不支持朋友圈分享。
FAQ
1. Q: 不同生命周期之间如何进行流程调度?
A: 根据生命周期规则,当方法为异步时 两者不互相阻塞, 如果有明确的关系,可以自行调度
例如
async onLoad(){
// 创建一个resolver promise, 并且抛出 resolver 供外部调用
let resolver = () => {}
$w.page.dataset.state.promise = new Promise((resolve)=>{
resolver = resolve
}):
// .... do something
// 需要的时候触发 resolver,此时 promise 转为 resolve 状态
resolver()
}
async onShow() {
/**
* 阻塞等待 promise 状态改变
* 当 promise resolve 之后,才进行之后的逻辑
*/
await $w.page.dataset.state.promise
}