专栏首页C++核心准则原文翻译微信小程序生命周期学习笔记-组件

微信小程序生命周期学习笔记-组件

生命周期包含应用生命周期、页面生命周期和组件生命周期。现在我们来学习组件的生命周期。

学习这一章节之前,需要先学习以下内容:

1.小程序的组件、自定义组件

2.页面节点树

3.应用生命周期、页面生命周期(重点是探索的方法)

微信开放文档:组件的生命周期,指的是组件自身的一些函数,这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发。

和应用(小程序)和页面一样,小程序的组件也同样拥有生命周期。如果你能够理解上文所介绍的页面生命周期,那么组件生命周期对你而言便不成问题。

现在我们来介绍两种与组件有关的生命周期:一种是组件自身的生命周期,一种是组件所在页面的生命周期。

我们先来新建一个自定义组件,然后打开这个组件的js文件。不同于我们在学习应用生命周期和页面生命周期时所看到的全局js文件和页面的js文件,新建组件时的js文件中没有对组件生命周期函数进行定义。我们需要自己来写生命周期函数并进行相应的测试。

组件自身的生命周期

我们先来看看组件自身有哪些生命周期函数:

生命周期

参数

描述

created

在组件实例刚刚被创建时执行

attached

在组件实例进入页面节点树时执行

ready

在组件在视图层布局完成后执行

moved

在组件实例被移动到节点树另一个位置时执行

detached

在组件实例被从页面节点树移除时执行

error

Object Error

每当组件方法抛出错误时执行

其中moved涉及到组件间关系的相关内容,难度较高,与前两个生命周期的关联程度也较少,这里暂时不做详细介绍。

在介绍各个生命周期函数之前,我们先要对生命周期函数的定义做一点说明:

在新建的js文件当中,我们能够看到开发者工具为我们创建好的框架如下:

根据微信开放文档给我们的建议,我们最好不要把组件自身的这些生命周期函数直接在与properties、data、methods同层级下声明,而是在这一层级下的lifetimes里声明,例如:

properties: {

},

lifetimes: {
    //在这里定义组件自身的生命周期函数
},

created

组件何时被小程序创造出来?当组件所在页面被调出来时,由于组件在页面wxml中被调用,此时组件必须被创造出来,否则无法在这个页面当中使用。

和之前一样的测试方法,给出测试代码(放在lifetimes中):

lifetimes:{
    created: function() {
      console.log("created");
    }
}

有了前面的学习和练习,那么这段代码在做什么样的事情我们就不必再说明了。当我们打开一个含有这个组件的页面时,我们就可以看到console中有“created”字符串输出。

那么它和页面的一些生命周期函数的调用顺序如何呢?

我们接下来把之前学习的页面周期函数中的输出全部加在页面的js文件中,来看一下效果:

也就是说,created的调用时间点在page.onLoad之前,即组件的创建在页面的加载(初始化)之前。

attached

根据我们刚刚看到的表格,attached函数是在组件实例进入页面节点树时执行。组件实例需要先被创建,然后才能进入页面节点树(有关页面节点树相关问题在这里不作详细说明)。所以我们可以得出,attached函数是在created函数之后执行。

用代码测试一下:

lifetimes:{
    attached: function() {
      console.log("attached");
    }
}

事实与我们的推断相符。

那么attached和页面生命周期执行的先后顺序如何?大家可以自行尝试。

结果是attached执行时间点晚于created,早于page.onLoad。说明页面加载的过程中包含组件实例进入页面节点树,也就是说组件是页面的必要成分(如果这个页面有组件的话),组件不先安置好,是没有办法完整加载页面的。

ready

ready函数是在组件在视图层布局完成后执行。你可能会有些迷惑,视图层布局完成是什么意思?是在手机页面渲染的过程?还是在构建页面视图、也就是在页面加载的过程中完成的?解决问题的办法,还是测试。

代码如下:

lifetimes:{
    ready: function() {
      console.log("ready");
    }
}

具体是在什么时候,大家可以同样把用页面生命周期的输出做比对,你会发现:

(这里面有两个ready,其中ready是组件生命周期ready函数中输出的,Ready是页面生命周期onReady函数输出的)

在学习页面生命周期时,我们就学习过,onLoad是在页面加载结束后执行,而这个时间点也是onShow的执行时间点,只是前者先于后者执行。这里面我们会发现,ready是晚于Show的,说明这个组件渲染结束是在页面加载结束后,在手机端进行页面渲染时,页面中的组件渲染结束后执行的。页面基本都不止含有组件,所以页面渲染完成的时间点一般情况下都会在组件渲染结束之后。

detached

detached这个词和attached长得很像,我们也知道,英文单词中的前缀de-有时表示反义。那么说明detached和attached是反义词。

attached是在组件实例进入页面节点树时执行,那显而易见,detached就是在组件实例被从页面节点树移除时执行。怎么移除?一个有组件的页面被卸载的过程中,必然要经过组件被移除的过程。

我们先来测试一下detached函数执行的时间点。

lifetimes:{
    detached: function() {
      console.log("detached");
    }
}

在测试前我们可以回想一下,当一个页面被卸载时,页面生命周期函数onUnload会被执行。那么究竟是onUnload函数先执行,还是detached函数先执行?在测试之前,我们可以先猜一猜最后结果是什么。

接下来要公布结果了:

和你猜的结果是否一样呢?

对于这个结果,我们有一个简单的理解方法:我们在学习onUnload时,学到他是监听页面卸载时执行的。那它是卸载之前执行还是卸载之后执行呢?我们可以这样去想,如果页面被卸载后再执行,而页面已经被卸载了,理论上这个页面不会再跑代码了。那么这个onUnload该如何执行?或者从它的作用出发思考,onUnload是我们在页面被卸载时实现一些我们想做的功能,说明这个功能只能在这个即将被卸载的页面上执行。页面被卸载了,那又该如何执行呢?

所以我们也就可以理解为什么onUnload是在卸载之前执行了。既然如此,我们又知道,卸载组件一定是在卸载页面的过程当中,也就是说,在卸载过程之前执行的onUnload一定会早于在卸载页面过程当中、在卸载组件之前(思考方式和onUnload一样)执行的detached。

error

error可是一个熟面孔了。我们在应用生命周期就学过onError,其实组件自身生命周期的error和onError没什么两样,同样要传递一个参数,这个参数是一个Object,用来记录错误信息的。

那么就给出测试代码,大家用学习onError时我们使用的方法,试一试这个error函数吧!打印一个字符串“error”,并输出错误信息。

代码如下:

lifetimes:{
    error: function(err) {
      console.log("error");
      console.log(err);
    }
}

如何引发错误呢?大家在编写组件时可以试着做一个事件绑定,在js中写函数时加入一行错误代码即可。这样在触发绑定的事件时就会弹错,console就会输出“error”和字符串,以及和红框中完全相同的错误信息(一样的错误信息会看到两个,一个是红底的,是工具自带的,一个是我们代码里输出的)。

理论上“error”字符串和我们输出的灰底的错误信息是挨在一起的,并且在红底的错误信息的上方。(其实这也说明工具提供错误信息的时间点在组件生命周期之后)。

组件所在页面的生命周期

微信开放文档:还有一些特殊的生命周期,它们并非与组件有很强的关联,但有时组件需要获知,以便组件内部处理。这样的生命周期称为“组件所在页面的生命周期”。

可用的组件所在页面的生命周期有以下三种:

生命周期

参数

描述

show

组件所在的页面被展示时执行

hide

组件所在的页面被隐藏时执行

resize

组件所在的页面尺寸变化时执行

学习过页面生命周期,这些函数对我们来说都很好理解。

在学习之前我们要说明这三个组件所在页面的生命周期的声明位置。和组件自身的生命周期相似,在小程序中不建议将这些生命周期直接命名在Components之中,也就是不建议与上文的lifetimes同层级。我们的定义方法是该层级中的pageLifetimes(L是大写!)里面声明。

有了页面生命周期和组件自身的生命周期的学习,这些函数的测试方法相信大家已经能够掌握。我们这里就不再过多叙述,只将测试代码一起给出,希望大家自己尝试测试。

其中resize函数的测试较为特殊,需要启用屏幕旋转支持。本节不对此进行详细描述,详见微信开放文档:响应显示区域变化

https://developers.weixin.qq.com/miniprogram/dev/framework/view/resizable.html#在手机上启用屏幕旋转支持

pageLifetimes: {
    show: function() {
      console.log("page-show");
    },

    hide: function() {
      console.log("page-hide");
    },

    resize: function() {
      console.log("page-resize")
    }
}

小结

到这里小程序的三种生命周期就全部介绍完了。这三种生命周期的理解,对自己想实现的许多功能都有很大的帮助。假如我们在之前提到的:在将小程序切入后台时,一些计时器不应该继续计时;如何判断使用小程序的人是否分享了这个小程序;使用的这个组件与页面相关,当这个页面被打开时,组件有这样的功能,关闭时又有那样的效果……通过学习,这些情况的实现方法,相信大家心中已经有答案了。

我们在学习过程中,也提到了输出探索的方法,这也是学习这方面内容的一个比较重要的学习方法。其实通过生命周期的学习,我们也在着重培养一个学习方式,有一部分的测试是让读者自己来完成的。如果这些任务读者都可以自己完成,并得出结论,那么这一部分的内容便是真正掌握了。

事实上这三种生命周期有很多地方都是共通的,学会了应用生命周期,我们就可以举一反三,在学习之前就可以想象出页面和组件的生命周期是什么样子的,是什么样的原理。在学习微信小程序、乃至整个信息技术的各个领域都是一样,我们在学习新知识时,或许都能找到一些我们之前学到过的知识的影子,与那些知识联系起来,构建新知识的架构,对这些新知识的理解会更进一步。

希望对生命周期的这些介绍与讲解对大家有帮助!

本文分享自微信公众号 - 面向对象思考(OOThinkingDalian),作者:面向对象思考

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 微信小程序生命周期学习笔记-页面篇

    小程序的生命周期分三类:应用生命周期、页面生命周期、组件生命周期。现在我们来学习一下页面的生命周期。

    面向对象思考
  • C++核心准则C.46:默认状态下明确定义单参数构造函数

    C.46: By default, declare single-argument constructors explicit

    面向对象思考
  • 微信小程序的自定义组件(入门)

    我们知道,在我们设计微信小程序时,我们经常会用到开发者工具中提供的许多标签,例如:

    面向对象思考
  • 微服务架构之服务冶理Dubbo-Netty流程

    服务引用时流程会走到DubboProtocol#refer方法,之前篇章中没有提及Netty环节,本节补上

    公众号_松花皮蛋的黑板报
  • 分享这半年的 Electron 应用开发和优化经验

    2019 年最后一发,谈谈这半年 Electron 应用开发和优化心得。干货也挺多,希望能给你带来一点启发。

    _sx_
  • 一个java高级工程师的进阶之路

    美的让人心动
  • 七问癌症“登月计划”:真靠谱,抑或仅仅是政治噱头?

    大数据文摘
  • SCI-hub打不开?小编亲自教你如何下载

    最近,有不少热心朋友询问,上次发的Sci-Hub还活着,只是你们不知道最新的网址而已。看过之后还不知道如何使用,或者说自己打不开,原以为大家知道如何使用,实际上...

    企鹅号小编
  • Vue vant引入,tabbar封装使用示例

    tabbar使用教程:https://youzan.github.io/vant/#/zh-CN/tabbar

    宣言言言
  • 解决H5在IOS的WebView下上拉下拉会带动整个WebView出现空白

    做Web应用,碰到问题,当拖动页面的时候,IOS的整个WebView会被拖动,导致上下方有灰色空白出现,并且影响内部滑动的体验。 在网上找了个神秘代码,大概意...

    饮水思源为名

扫码关注云+社区

领取腾讯云代金券