【微信小程序开发•系列文章六】生命周期和路由
这篇文章理论的知识比较多一些,都是个人观点,描述有失妥当的地方希望读者指出。
- 【微信小程序开发•系列文章一】入门
- 【微信小程序开发•系列文章二】视图层
- 【微信小程序开发•系列文章三】数据层
- 【微信小程序开发•系列文章四】模块化
- 【微信小程序开发•系列文章五】主界面
- 【微信小程序开发•系列文章六】生命周期和路由
整个微信小程序从打开到关闭,整个过程可以分为很多阶段或者说状态,这一整段的过程,我们称之为小程序的生命周期。而周期中的每种不同的状态,到另一个状态的过度和转化,是需要一个触发机制的,这种机制我们称之为路由。
一、生命周期

先来分析一下小程序官网给的这张图,它指的是Page的整个生命周期。要理解它,我们还是先回顾一下React.js的渲染机制。
react里面有一个virtual DOM的概念,它实际上是把界面中的每个元素,用js实现的树形数据结构对应起来,结构里记录了节点的所有信息。我们可以把这个virtual DOM看成一个独立的线程(js里没有真正的多线程),我们暂时称它为view线程,它的工作就是负责界面的渲染。当virtual DOM上的数据发生变化的时候,界面的相应的部分就会跟着更新,更新机制被称为DOM diff,这里有篇文章详细地分析了这种更新机制:http://calendar.perfplanet.com/2013/diff/,不过可惜的是它要FQ才能看,后面发现segmentfault上有人把它转成中文描述了:https://segmentfault.com/a/1190000000606216,有兴趣的读者可以阅读一下这篇文章。
这里简单地介绍下:React.createClass创建的类都有一个render方法,它返回的不是真正的html代码,而是我们上面讲到的virtual DOM,每一次渲染会直接按内部转换关系画到界面上,这个流程跟传统的网页渲染差不多。但是当要修改界面上某些元素的时候,react的性能才会真正的突显出来,它会去调用setState方法,这时有内置的算法会去比对这次操作引起的变化前后,最小的差异是什么,然后把这个最小的差异更新到界面上。DOM diff的这篇文章讲到,传统的两个树形结构要分析出差异,复杂度至少要O(n^3),但react巧妙地把这个复杂度做到了接近O(n),优化了非常多,这也是它的核心算法。
这整个东东,就是我们上面讲到的“view线程”,它负责拿到数据后去做界面的更新,不过这个“线程”不处理主业务逻辑,只负责view层,用react的时候,它的内部框架已经帮我们做好了,所以react被称为是一个view层的框架。
那么我们还需要一个“线程”来处理主逻辑,这些就是我们自己要写的主要的代码。微信小程序跟react一样,也帮我们做好了这种渲染的算法。上图中,左侧绿色的部分,可以理解为上文中的“view线程”,应用启动时,他会用Page里的data初始值去Init出一个初始的virtual DOM,当setData被调用的时候,MINA就会触发我们上面讨论的DOM diff的过程,自动去更新界面。这也是为什么我们直接修改data无效的原因,一定要调用setData界面才会有变化。
上图右侧的“AppService线程”,其实就是我们说的主业务逻辑“线程”,我们就是跟它打交道。
下面简述一下整个生命周期的过程:
“view线程”和“AppService线程”在Page({… })被执行时差不多同时启动(实际上,个人理解,后者应该要先一步启动,因为它要接收notify,纯属猜测)。前者init结束时,发送一个notify到后者。后者在create完成后,会同时触发Onload和Onshow回调(至于为什么要同时触发两个看起来差不多的状态,在下方会分析到),在这两个函数里面对page的data做一些修改(setData),然后挂起进入等待状态,等“view线程”init完,才会进行下面的流程,因为对用户来说这个应用的直接使用方式就是界面,背后逻辑用户不管,所以一定要等“view线程”准备好后,再做下面的事情才有意义。
如果Onload和Onshow有对data做修改,收到notify通知前也不会做什么动作,直到收到通知才会把变化发送给“view线程”,之后的流程里,setData就不用等通知了,因为这个通知只是为了让“AppService线程”知道“view线程”已经准备好了,进入可用状态了,后面就可以随意setData了,“view线程”随时都会做出响应,一发现数据变化就会重新render然后做DOM diff操作,去更新界面。
而当用户进入另一个页面时(wx.nativateTo),onHide函数被触发,页面被切换到后台,可以看成是挂起状态,不会有什么动作。而当用户切换回来的时候(wx.navigateBack),onShow会被触发,但onLoad不会,onLoad只会在page初始化完成时触发一次,后面不会再进入了,所以对于只需要做一次的操作,千万不要写到onShow里面,如请求页面初始数据,要写到onLoad里。上面讲到“AppService线程”初始化的时候要同时触发onShow和onLoad,虽然字面上理解起来比较相似,但其实是不一样的过程,触发条件也是不一样的。
二、路由

路由的控制逻辑主要在WAService.js里,这个文件,当程序在运行时,调试工具里可以查看。可惜的是,这个文件是压缩过的,格式化之后,还是很难看懂主要的逻辑。不过上表微信官方给的也表述得比较明显。
大概按这表介绍下路由的几种情况。
(1)当程序打开的时候,第一个页面会被加载(第一个页面,指在app.json里的pages配置的第一项),先初始化,这时这个页面的onLoad和onShow会被调用。
(2)从第一个页面跳到其它页面(navigateTo),这时第一个页面的onHide会被调用,跳过去的其它页面onLoad和onShow会被调用。
(3)如果是redirectTo跳转,则第一个页面被触发的是onUnload,其它跟(2)一样
(4)页面返回时,前一个页面被onUnload卸掉,返回后的页面onShow被调用。从这可以看出,返回时,前一个页面被销毁了。
(5)tab的切换,就只有onShow和onHide,当然第一个出现页面还有一个onLoad。
这几个情况也比较直观。
【微信小程序开发•系列文章六】生命周期和路由的更多相关文章
- 微信小程序开发之详解生命周期方法
生命周期是指一个小程序从创建到销毁的一系列过程 在小程序中 ,通过App()来注册一个小程序 ,通过Page()来注册一个页面 先来看一张小程序项目结构 从上图可以看出,根目录下面有包含了app.js ...
- 微信小程序开发系列六:微信框架API的调用
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 微信小程序开发系列四:微信小程序 ...
- 微信小程序开发系列七:微信小程序的页面跳转
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 微信小程序开发系列四:微信小程序 ...
- WordPress版微信小程序开发系列(二):安装使用问答
自WordPress版微信小程序发布开源以来,受关注的程度超过我原来的想象.这套程序主要面对的用户是wordpress网站的站长,如果wordpress站想在微信的生态圈得到推广,小程序成为一种重要的 ...
- 微信小程序开发系列五:微信小程序中如何响应用户输入事件
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 微信小程序开发系列四:微信小程序 ...
- 微信小程序开发系列二:微信小程序的视图设计
大家如果跟着我第一篇文章 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 一起动手,那么微信小程序的开发环境一定搭好了.效果就是能把该小程序的体验版以二维码的方式发送给其他朋友使用. 这个系列 ...
- 微信小程序开发系列教程三:微信小程序的调试方法
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 这个教程的前两篇文章,介绍了如何用下图所示的微信开发者工具自动生成一个Hel ...
- 微信小程序开发系列四:微信小程序之控制器的初始化逻辑
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 这个教程的前两篇文章,介绍了如何 ...
- 微信小程序onLaunch、onLoad执行生命周期
原文转载自:微信小程序onLaunch.onLoad执行生命周期 1.需求:先执行App的onLaunch添加验证权限等,再执行Page里的onLoad. 2.问题:还没有等onLaunch执行完成, ...
随机推荐
- 理解Maven中的SNAPSHOT版本和正式版本
Maven中建立的依赖管理方式基本已成为Java语言依赖管理的事实标准,Maven的替代者Gradle也基本沿用了Maven的依赖管理机制.在Maven依赖管理中,唯一标识一个依赖项是由该依赖项的三个 ...
- 探索C#之6.0语法糖剖析
阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...
- Sublime Text3配置在可交互环境下运行python快捷键
安装插件 在Sublime Text3下面写代码感觉很不错,但是写Python的时候遇到了一些问题. 用Sublime Text3打开python文件,或者在Sublime Text3下写好pytho ...
- 关于Raid0,Raid1,Raid5,Raid10的总结
RAID0 定义: RAID 0又称为Stripe或Striping,它代表了所有RAID级别中最高的存储性能.RAID 0提高存储性能的原理是把连续的数据分散到多个磁盘上存取,这样,系统有数据请求就 ...
- ZKWeb网页框架1.3正式发布
本次更新的内容有 更新引用包版本 Microsoft.AspNetCore.Hosting.Abstractions 1.1.0 Microsoft.AspNetCore.Http.Abstracti ...
- 安装angular-cli
最近在学习angular2,并尝试用这个框架来做公司的一个新项目. 终于要开始开发了,等了1个多月. 因为第一次用这个新框架做项目,不太熟悉,就找了angular-cli这个脚手架来搭建项目. 安装了 ...
- windows 7(32/64位)GHO安装指南(U盘制作篇)~
本篇接着上篇的介绍,为同学讲解U盘启动盘的制作.虽然本篇大白菜的官网上也有类似的教程,但是为了完整性,我将在这里为大家细细的讲解.在这里说一下,系统包和软件包的下载大家可以自行下载,很简单的,小主就不 ...
- 学习笔记 :DrawText
最近在做一个TStringGrid的自绘处理,在画文字处理上遇到了高度的计算问题.后来经过一段时间还是找到了一些方法: 1.使用TLabel 这个方法是有点绕路的,方法倒是简单,就是使用AutoSiz ...
- 【流量劫持】沉默中的狂怒 —— Cookie 大喷发
精简版:http://www.cnblogs.com/index-html/p/mitm-cookie-crack.html 前言 上一篇文章 讲解了如何借助前端技术,打造一个比 SSLStrip 更 ...
- Linux学习日记(二)
在linux上运行.Net程序 并安装Linux网站 一.环境 ubuntu14.10(桌面版 官网下载的最新版) jexus5.6.3 正式版 MonoDevloper (安装完后里面有个Ubunt ...