mpvue是美团基于vue开发的一个开发小程序的框架,从而以vue的语法来开发小程序。在生命周期上,mpvue同时支持了vue的生命周期和小程序的生命周期,这可能让新上手的同学费解。这篇文章就来讲讲mpvue的混合生命周期。

一个bug

在深入之前,先说一个mpvue开发中的常见的坑。假设你在一个页面中有打开了一个弹窗,然后在没有关闭的情况下返回上一页,然后再重新进入时,弹窗依然在那里。按道理说,返回上一页时,弹窗所在的page实例已经被unload了,为什么再次进入弹窗还在呢,这其实是mpvue混合生命周期搞的鬼。

mpvue的生命周期

在理解mpvue的生命周期前,我们先看一下官方给出的一张图:

不得不说这张图做的真心有点糙,mpvue本来就不需要传el这个option,结果还是出现在生命周期图示中。。。将el换成page实例倒是更贴切一些。相信不少同学对mpvue的生命周期还是有点晕的。下面我们重新梳理一下各个钩子在什么时候触发。

这里以官方的mpvue/mpvue-quickstart项目来演示小程序的生命周期函数到底在什么时候触发,项目代码可以参考官方教程获得。

console.log

研究触发过程的做法简单粗暴,就是直接在各个生命周期函数下打console.log。mpvue-quickstart有3个页面,分别是index,counter和logs,下面我们给这3个页面加上如下生命周期函数:

 created() {
console.log('page index created', this)
},
mounted() {
console.log('mounted', this)
},
onLoad() {
console.log('page index onLoad', this)
},
onReady () {
console.log('page index onReady', this)
},
onShow() {
console.log('onShow', this)
},
onUnload() {
console.log('onUnload', this)
},
onHide() {
console.log('onHide', this)
},

完成后,重新编译小程序,控制台打印的日志如下图,分析可以看出以下结论:

  1. vue的created函数先于小程序onLoad函数调用

  2. 一个页面对应一个vue实例,app也对应一个vue实例(打印出的this)

  3. 在小程序的第一页出现前,已经创建出了所有页面对应的Vue实例。看下图可以看出,在index页面的onLoad触发前,page counter,logs的created函数已经触发。

  4. mounted会在onReady之后触发,这个钩子适用于当页面出现时执行一些过渡效果的情况。

有同学可能会以为vue的实例是和小程序的page实例一起出现的,然而事实并不是这样。

vue的实例在页面显示之前就已经被初始化了,也就是在main.js中执行new vue(App)的时候。而小程序的页面则是按需加载的,当用户跳转到那个页面时,page实例才会创建。这个观点同样可以由vue实例下面的$mp属性说明,这个属性关联了vue的实例和小程序页面的实例。

Tips: 当你需要使用wx.createSelectorQuery() 查询某个元素的位置时,应当放在onReady或者mounted的生命周期中进行,保证位置的准确性

$mp属性

这个属性在原生vue中是没有的,它是由mpvue扩展出的属性,可以类比原生vue中的\(el。在网页中,\)el指向vue驱动的dom元素。而在小程序中,$mp指向vue驱动的page或者app实例。

下面我们看看index和counter两个页面对应的vue实例下$mp属性的区别:

当页面load后,\(mp为ready状态,并且有page属性指向这个页面实例,而页面还没有load时,\)mp属性为register状态,没有page属性。也就是说,空有vue实例,但是并没有page可以给他操作。

onUnLoad方法调用后,相应页面vue实例还在吗?

上面是在onUnload生命周期函数下打印的this,可见this也就是vue实例并没有被销毁,而小程序的page实例被销毁了。所以vue内部的状态会被保存,如弹窗打开关闭的状态。假设这个状态由this.showModal控制

data(){
return {
showModal: false// 弹窗为关闭状态
}
}

当页面再次被打开时,如果上次页面this.showModal为true,则页面刚出现时弹窗就还是打开的。这就解释了文章一开头的那个问题。所以,如果你希望当页面被关闭时,状态不被保存的话,需要在onUnload方法下处理相关逻辑,或者在onShow时重置data里的状态

// ...
onUnload(){
this.showModal = false
}
// 更通用一点
onUnload() {
Object.assign(this, this.$options.data())
}

总结:尽管mpvue同时支持了小程序的生命周期和vue的生命周期,但是两者之间并不是共生共灭的关系。更多阅读可以参考这个官方仓库的issue-同一路由切换时,上一次的页面数据会保留 #140

理解mpvue的生命周期的更多相关文章

  1. 理解Fragment的生命周期

    与活动类似,Fragment也有自己的生命周期.理解Fragment的生命周期有助于在Fragment销毁时能恰当地保存其实例,然后在重新创建时能够将其恢复至之前的状态. 下面的“试一试”将研究Fra ...

  2. 我理解的vue生命周期

    说些题外话,引出vue的生命周期. 比如人出生到寿终正寝,这是人的一个生命周期.他会经历出生,婴儿时期,童年时期,少年时期,青年,中年,老年,到 end.然后,每个时期都会有一定的历史任务在等着去完成 ...

  3. Maven - 深入理解maven构建生命周期和各种plugin插件

    作者:亚当-adam 来源:CSDN 原文:https://blog.csdn.net/zhaojianting/article/details/80321488 版权声明:本文为博主原创文章,转载请 ...

  4. 深入理解Vue的生命周期

    谈到Vue的生命周期,相信许多人并不陌生.但大部分人和我一样,只是听过而已,具体用在哪,怎么用,却不知道.我在学习vue一个多礼拜后,感觉现在还停留在初级阶段,对于mounted这个挂载还不是很清楚. ...

  5. 深入理解android view 生命周期

    作为自定义 view 的基础,如果不了解Android  view 的生命周期 , 那么你将会在后期的维护中发现这样那样的问题 ....... 做过一段时间android 开发的同学都知道,一般 on ...

  6. 【SpringBoot】SpringBoot的基础,全面理解bean的生命周期

    前言 前段时间直接上手使用springboot开发了一个数据平台的后台部分,但是自身对于springboot的原理和过程还不是很清晰,所以反过来学习下springboot的基础. 大家都知道sprin ...

  7. [转载]深入理解maven构建生命周期和各种plugin插件

    我就不复制博主文章了,到原文地址看吧.写这个只是为了自己搜索起来方便些: https://blog.csdn.net/zhaojianting/article/details/80321488 htt ...

  8. springMVC源码阅读-通过画图理解一个请求生命周期(十二)

  9. (十)深入理解maven构建生命周期和各种plugin插件

    链接:https://blog.csdn.net/zhaojianting/article/details/80321488

随机推荐

  1. SPL之Iterator和ArrayAccess的结合使用

    <?php namespace TabControl; class MyIterator implements \Iterator, \ArrayAccess { private $data = ...

  2. loj#528. 「LibreOJ β Round #4」求和

    求:\(\sum_{i=1}^n\sum_{j=1}^m\mu(gcd(i,j))^2\) 化简可得\(\sum_{i=1}^{min(n,m)}{\lfloor \frac{n}{i} \rfloo ...

  3. UI BOL 练习 get value set attr

    " " " " "**********************change list************************* "2 ...

  4. 【LeetCode】字符串匹配

    给定目标串 haystack 和模式串 needle ,返回 needle 在 haystack 中第一次出现的位置下标,若 needle 不是 haystack 的子串则返回 -1. 1. Brut ...

  5. Python爬虫原理

    前言 简单来说互联网是由一个个站点和网络设备组成的大网,我们通过浏览器访问站点,站点把HTML.JS.CSS代码返回给浏览器,这些代码经过浏览器解析.渲染,将丰富多彩的网页呈现我们眼前: 一.爬虫是什 ...

  6. 【转】JS常用函数整合库 lutils

    lutils 此工具包是在 outils 的基础上,加上个人平时收集的代码片段进行的二次整合 outils的GitHub:https://github.com/proYang/outils/blob/ ...

  7. 使用VAE、CNN encoder+孤立森林检测ssl加密异常流的初探——真是一个忧伤的故事!!!

    ssl payload取1024字节,然后使用VAE检测异常的ssl流. 代码如下: from sklearn.model_selection import train_test_split from ...

  8. weblogic开启http访问日志并实时写入日志文件

    由于http访问会产生大量日志,耗去不少IO和CPU所以在生产一般是不启用的:但有时我们会想启用http访问日志,尤其是在系统上线调试的时候. weblogic的日志默认在domain_name/se ...

  9. py propterties reuqest.post

    import tracebackclass Properties(object): def __init__(self, fileName): self.fileName = fileName sel ...

  10. killl prefix out macro mis mal micro -m

    1● macro 宏大,规模大   2● mis 错误,坏   3● mal 坏,错误   4● micro 小,微小