《微信小程序七日谈》系列文章:

  1. 第一天:人生若只如初见
  2. 第二天:你可能要抛弃原来的响应式开发思维
  3. 第三天:玩转Page组件的生命周期
  4. 第四天:页面路径最多五层?导航可以这么玩

前两篇文章第一天:人生若只如初见第二天:你可能要抛弃原来的响应式开发思维零零散散地记录了一些微信小程序的细节,主要集中在UI方面。其中提到的解决方案只是笔者自身的一些探索,并非最佳实践,甚至不是笔者项目中最后采用的方案(最终方案会在后续文章里详细讲述)。其实小程序的UI开发并非简短的两篇文章可以概括的,还有许多细节待挖掘,奈何项目排期紧张,暂时就不去研究与当前需求无关的东西了。

今天这篇文章简单记录一下在使用小程序Page组件时对于其生命周期的一些使用心得。

钩子函数的命名技巧

官方文档对Page的生命周期的介绍简单明了,在生命周期的不同阶段抛出的钩子函数依次为: onLoad -> onShow -> onReady -> onHide -> onUnload

使用过React的开发者肯定会对用on做为钩子函数命名前缀非常不舒服,React使用will、did、should等一系列有时态语义的词汇命名钩子函数,令开发者一眼就能分辨钩子函数对应的生命周期阶段。但是on是具有一定歧义的。浏览器的用户行为事件机制,以及我们所熟悉的jQuery中,使用on作为捕获/监听事件的API命名,这种情形下可以把on理解为当某件事情发生时做某些行为,这也是大部分前端工程师对on语义的理解。这种理解的on有一层拦截的意思,比如onclick先于<a>href跳转,可以拦截其默认的click行为,在默认click之前发生。但是请大家仔细思考一下window.onloadon的含义。onload的触发时机是在文档加载完成之后,在执行我们定义的onload逻辑之前,文档已经完成了load行为。也就是说,onload并没有拦截load行为,而是在load事件之后发生。所以,on这个词汇并不能精准的形容到底是前还是后,它是没有时态语义的。

具体到Page的生命周期钩子函数,大家请凭第一感觉理解下面几个函数的执行时机:

  • onLoad
  • onShow
  • onReady

我相信大部分人对于这三者的理解是:钩子函数在load/show/ready完成之后执行。跟window.onload是一样的。那么请大家在思考下列两个的执行时机:

  • onHide
  • onUnload

跟前三者是一样的吗?

我们先不去探究后两者与前三者的执行时机策略是否相同。请大家先以常规的思维思考下列的应用场景:app导航栏左上角有个“返回”按钮,如下图:

很常见的一个逻辑是:如果用户在未保存表单数据之前点击返回按钮的话,通常会弹出一个提示层,如下:

也就是说,页面有个beforeUserLeave的策略,在执行userLeave之前进行拦截并给出提示,以免用户的操作失误。这不仅仅是业务逻辑的需求,也是一个网站从开始到被关闭过程中的一环,这就是我们熟知的window.onbeforeunload事件。

同样,笔者参与的项目也有上述的业务逻辑,在用户离开页面之前提示用户的编辑状态。对应小程序的几个钩子函数,结合React和Vue的开发经验,自然而然地就想到在onHide或者onUnload内拦截返回操作并给出提示。

但是,并不行!onHideonUnload的执行时机策略竟然跟onLoad/onShow/onReady一样!

也就是说,在page被卸载之后才会执行onUnload。这就造成用户点击返回按钮,已经回到了上一个页面,然后,突然弹出了一个提示框:

用户:WTF?

钩子函数的正确执行时机

其实官方文档详细展示了Page的各个钩子函数的执行时机,如下图:

从上图中可以看出:

  • onHide是在当前Page被“set to background”之后触发;
  • onUnload是在当前Page被“destory”之后触发。

当然,每个人设计组件时对组件的生命周期都有自己的理解和实现,并不是说小程序的Page生命周期设计的不好,只是希望能够提供更细化的钩子函数,比如上文提到的“before”策略,以便实现更人性化的用户体验。

data全部动态化

vue.js的1.x版本提供了activate钩子函数,这个钩子阻塞了组件的后续执行,方便开发者在组件渲染之前进行特殊处理,比如使用jsonp请求数据,成功后执行done()触发组件的后续流程。

小程序里有没有阻塞的钩子函数呢?

可能大部分人跟笔者一样,第一个想法就是试试onShow是否是阻塞的,但是结果并不像预期的那样。小程序的Page组件没有提供阻塞的钩子函数,根据上文中的官方配图可以看到,在组件的data更新之后有个"Rerender"动作。Page组件的数据统一为data,而不是像React或者Vue区分propsstate/data。这种设计的优点是不用特意的对某个data进行监听,data全部是动态的,这意味着任何一个data的改变都会触发Rerender。

小程序提供一些内置的UI组件,但是逻辑组件只有apppage两种,并且两者并不是严格的父子组件关系。所以,page组件并不需要类似React中的props数据,所有的数据都属于自身。

总结

Page组件的生命周期十分简洁,上手容易。但是面对一些特殊需求时并不能提供很好的支持。这种情况下我们不得不适当地修改需求逻辑。
小程序中并没有父子组件的关系谱,组件的数据不会区分propsstate,全部是统一的data,并且全部是动态的。任何data的修改都会触发Rerender。

最近发现有些网站、个人博客以及微信公众号未经授权转载了笔者的文章,作为技术人员,希望大家都具有基本的职业道德。剽窃的技术是不会得到尊重的,对于未经授权的转载方,必要的时候会付诸法律手段。

《微信小程序七日谈》- 第三天:玩转Page组件的生命周期的更多相关文章

  1. 《微信小程序七日谈》- 第四天:页面路径最多五层?导航可以这么玩

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 微信小 ...

  2. 《微信小程序七日谈》- 第二天:你可能要抛弃原来的响应式开发思维

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 上篇文 ...

  3. 《微信小程序七日谈》- 第一天:人生若只如初见

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 微信小 ...

  4. 《微信小程序七日谈》- 第五天:你可能要在登录功能上花费大力气

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩: 第五 ...

  5. 《微信小程序七日谈》- 第六天:小程序devtool隐藏的秘密

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩: 第五 ...

  6. 《微信小程序七日谈》- 第七天:不要捡了芝麻丢了西瓜

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩: 第五 ...

  7. 使用wepy开发微信小程序商城第三篇:购物车(布局篇)

    使用wepy开发微信小程序商城 第三篇:购物车(布局篇) 前两篇如下: 使用wepy开发微信小程序商城第一篇:项目初始化 使用wepy开发微信小程序商城第二篇:路由配置和页面结构 基于上两篇内容,开始 ...

  8. 微信小程序把玩(三十三)Record API

    原文:微信小程序把玩(三十三)Record API 其实这个API也挺奇葩的,录音结束后success不走,complete不走,fail也不走, 不知道是不是因为电脑测试的原因,只能等公测或者等他们 ...

  9. 微信小程序把玩(三十四)Audio API

    原文:微信小程序把玩(三十四)Audio API 没啥可值得太注意的地方 重要属性: 1. wx.getBackgroundAudioPlayerState(object) 获取播放状态 2.wx.p ...

随机推荐

  1. 炜煌T3POS58微打参数设置方法

     本文用菊子曰发布

  2. 在ArcGIS空间数据库中增加点数据的方法

    1.新建一个mxd(ArcMAP)文件 2.从ArcCatalog中把要编辑的图层拖到ArcMAP中 3.从ArcCatalog中拖一个参照图层到ArcMAP中,比如临沂市的县级区划图 4.打开Edi ...

  3. JavaScript中的CSS属性对照表

    盒子标签和属性对照 CSS语法(不区分大小写) JavaScript语法(区分大小写) border border border-bottom borderBottom border-bottom-c ...

  4. Java 周历日历

    WeekCalendarUtils工具类代码,传入起始日期即可返回对应日期的周历日历,年月部分添加周数统计 import java.util.Calendar; import java.util.Da ...

  5. IOS-TextField控件详解

    //初始化textfield并设置位置及大小 UITextField *text = [[UITextField alloc]initWithFrame:CGRectMake(20, 20, 130, ...

  6. Openresty 安装教程

    Openresty的简单安装方法,如需高级编译安装,请参照安装选项 1.安装配置好Yum源,不赘述此步骤 2.安装必要组件 yum install pcre-devel openssl-devel g ...

  7. Windows XP 中设置VPN(PPTP连接方式)

    第一步:点开始-网上邻居或者控制面板-网络连接,选择-创建一个新的连接 第二步:点击-下一步 第三步:选择-连接到我的工作场所的网络,点击-下一步 第四步:选择-虚拟专用网络连接,点击-下一步 第五步 ...

  8. Nginx负载均衡深入浅出

    nginx不单可以作为强大的web服务器,也可以作为一个反向代理服务器,而且nginx还可以按照调度规则实现动态.静态页面的分离,可以按照轮询.ip哈希.URL哈希.权重等多种方式对后端服务器做负载均 ...

  9. Xshell中文乱码问题

    1.  先查看当前使用的语言: echo $LANG 2.  查看系统的语言安装包: locale 3.  如果没有中文安装包(包含zh_CN字样),需要网络或者自己上传安装包,安装 4.  有了中文 ...

  10. ORA-12571: TNS:packet writer failure

    ORA-12571:TNS:包复写器失效 2007-05-28 22:04 ORA-12571:TNS:包复写器失效 近日一直在做Oracle数据库的搭建(入门),在搭建过程中遇到“ORA-12571 ...