《微信小程序七日谈》系列文章:html
本系列的文章并不是初学教程,而是笔者在具体开发过程当中遇到的问题以及部分解决方案。前端
前两篇文章第一天:人生若只如初见和次日:你可能要抛弃原来的响应式开发思惟零零散散地记录了一些微信小程序的细节,主要集中在UI方面。其中提到的解决方案只是笔者自身的一些探索,并不是最佳实践,甚至不是笔者项目中最后采用的方案(最终方案会在后续文章里详细讲述)。其实小程序的UI开发并不是简短的两篇文章能够归纳的,还有许多细节待挖掘,奈何项目排期紧张,暂时就不去研究与当前需求无关的东西了。vue
今天这篇文章简单记录一下在使用小程序Page组件时对于其生命周期的一些使用心得。json
官方文档对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.onload
中on
的含义。onload
的触发时机是在文档加载完成以后,在执行咱们定义的onload逻辑以前,文档已经完成了load行为。也就是说,onload
并无拦截load行为,而是在load事件以后发生。因此,on
这个词汇并不能精准的形容究竟是前仍是后,它是没有时态语义的。微信小程序
具体到Page的生命周期钩子函数,你们请凭第一感受理解下面几个函数的执行时机:浏览器
onLoad
onShow
onReady
我相信大部分人对于这三者的理解是:钩子函数在load/show/ready完成以后执行。跟window.onload
是同样的。那么请你们在思考下列两个的执行时机:微信
onHide
onUnload
跟前三者是同样的吗?前端工程师
咱们先不去探究后二者与前三者的执行时机策略是否相同。请你们先以常规的思惟思考下列的应用场景:app导航栏左上角有个“返回”按钮,以下图:
app
很常见的一个逻辑是:若是用户在未保存表单数据以前点击返回按钮的话,一般会弹出一个提示层,以下:
也就是说,页面有个beforeUserLeave
的策略,在执行userLeave
以前进行拦截并给出提示,以避免用户的操做失误。这不只仅是业务逻辑的需求,也是一个网站从开始到被关闭过程当中的一环,这就是咱们熟知的window.onbeforeunload
事件。
一样,笔者参与的项目也有上述的业务逻辑,在用户离开页面以前提示用户的编辑状态。对应小程序的几个钩子函数,结合React和Vue的开发经验,天然而然地就想到在onHide
或者onUnload
内拦截返回操做并给出提示。
可是,并不行!onHide
和onUnload
的执行时机策略居然跟onLoad/onShow/onReady
同样!
也就是说,在page被卸载以后才会执行onUnload
。这就形成用户点击返回按钮,已经回到了上一个页面,而后,忽然弹出了一个提示框:
用户:WTF?
其实官方文档详细展现了Page的各个钩子函数的执行时机,以下图:
从上图中能够看出:
onHide
是在当前Page被“set to background”以后触发;onUnload
是在当前Page被“destory”以后触发。固然,每一个人设计组件时对组件的生命周期都有本身的理解和实现,并非说小程序的Page生命周期设计的很差,只是但愿可以提供更细化的钩子函数,好比上文提到的“before”策略,以便实现更人性化的用户体验。
vue.js的1.x版本提供了activate钩子函数,这个钩子阻塞了组件的后续执行,方便开发者在组件渲染以前进行特殊处理,好比使用jsonp请求数据,成功后执行done()
触发组件的后续流程。
小程序里有没有阻塞的钩子函数呢?
可能大部分人跟笔者同样,第一个想法就是试试onShow
是不是阻塞的,可是结果并不像预期的那样。小程序的Page组件没有提供阻塞的钩子函数,根据上文中的官方配图能够看到,在组件的data更新以后有个"Rerender"
动做。Page组件的数据统一为data
,而不是像React或者Vue区分props
和state/data
。这种设计的优势是不用特地的对某个data进行监听,data所有是动态的,这意味着任何一个data的改变都会触发Rerender。
小程序提供一些内置的UI组件,可是逻辑组件只有app
和page
两种,而且二者并非严格的父子组件关系。因此,page
组件并不须要相似React中的props
数据,全部的数据都属于自身。
Page组件的生命周期十分简洁,上手容易。可是面对一些特殊需求时并不能提供很好的支持。这种状况下咱们不得不适当地修改需求逻辑。
小程序中并无父子组件的关系谱,组件的数据不会区分props
和state
,所有是统一的data
,而且所有是动态的。任何data的修改都会触发Rerender。
最近发现有些网站、我的博客以及微信公众号未经受权转载了笔者的文章,做为技术人员,但愿你们都具备基本的职业道德。剽窃的技术是不会获得尊重的,对于未经受权的转载方,必要的时候会付诸法律手段。