美文网首页让前端飞Web前端之路虾写前端
理解vue实例的生命周期和钩子函数

理解vue实例的生命周期和钩子函数

作者: 四小七 | 来源:发表于2018-06-21 15:06 被阅读135次

虽然经常使用mounted、created等几个钩子函数,但是并没有很系统的将它和生命周期关联一起去理解,这导致我在最近项目里踩了坑。所以现在花点时间,整理一下这方面的知识。

我的其他文章,也可以了解一下:
【使用vue-cli(vue脚手架)快速搭建项目】:https://www.jianshu.com/p/1ee1c410dc67
【vue之父子组件间通信实例讲解(props、$ref 、 $emit )】:
https://www.jianshu.com/p/91416e11f012
【vue之将echart封装为组件】:
https://www.jianshu.com/p/ec39019e2141

1. vue实例的生命周期

通俗来说 vue的生命周期就是vue实例从创建到销毁的过程,我将这个过程中的一些关键点抽取出来,简化为下面这个流程图:


生命周期

2. 结合生命周期理解钩子函数

vue2.0提供了一系列钩子函数,这些函数和生命周期的各个阶段一一对应:


生命周期和钩子函数
钩子函数 描述
beforeCreate 组件实例刚被创建,组件属性计算之前,如data属性等
created 组件实例创建完成,属性已绑定,但DOM还未生成,$el属性还不存在
beforeMount 模板编译 / 挂载之前
mounted 模板编译 / 挂载之后
beforeUpdate 组件更新之前
update 组件更新之后
activated 组件被激活时调用
deactivated 组件被移除时调用
beforeDestory 组件销毁前调用
destoryed 组件销毁后调用

3. 结合代码理解钩子函数

为了更深入的理解各个钩子函数的区别,我们结合代码去看看:

<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>
<script type="text/javascript">
  export default {
    data(){
      return{
        message : "钩子函数小测试"
      }
    },
    beforeCreate(){
      console.group('beforeCreate 创建前状态 ------------>');
      console.log("%c%s", "color:red" , "el     : " + this.$el); //undefined
      console.log("%c%s", "color:red","data   : " + this.$data); //undefined
      console.log("%c%s", "color:red","message: " + this.message)
    },
    created() {
      console.group('created 创建完毕状态 ------------>');
      console.log("%c%s", "color:red","el     : " + this.$el); //undefined
      console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
      console.log("%c%s", "color:red","message: " + this.message); //已被初始化
    },
    beforeMount() {
      console.group('beforeMount 挂载前状态 ------------>');
      console.log("%c%s", "color:red","el     : " + (this.$el)); //已被初始化
      console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
      console.log("%c%s", "color:red","message: " + this.message); //已被初始化
    },
    mounted() {
      console.group('mounted 挂载结束状态 ------------>');
      console.log("%c%s", "color:red","el     : " + this.$el); //已被初始化
      console.log(this.$el);
      console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
      console.log("%c%s", "color:red","message: " + this.message); //已被初始化
    },
    beforeUpdate() {
      console.group('beforeUpdate 更新前状态 ------------>');
      console.log("%c%s", "color:red","el     : " + this.$el);
      console.log(this.$el);
      console.log('真实dom结构:' + document.getElementById('app').innerHTML);
      console.log("%c%s", "color:red","data   : " + this.$data);
      console.log("%c%s", "color:red","message: " + this.message);
    },
    updated() {
      console.group('updated 更新完成状态 ------------>');
      console.log("%c%s", "color:red","el     : " + this.$el);
      console.log(this.$el);
      console.log('真实dom结构:' + document.getElementById('app').innerHTML);
      console.log("%c%s", "color:red","data   : " + this.$data);
      console.log("%c%s", "color:red","message: " + this.message);
    },
    beforeDestroy() {
      console.group('beforeDestroy 销毁前状态 ------------>');
      console.log("%c%s", "color:red","el     : " + this.$el);
      console.log(this.$el);
      console.log("%c%s", "color:red","data   : " + this.$data);
      console.log("%c%s", "color:red","message: " + this.message);
    },
    destroyed() {
      console.group('destroyed 销毁完成状态 ------------>');
      console.log("%c%s", "color:red","el     : " + this.$el);
      console.log(this.$el);
      console.log("%c%s", "color:red","data   : " + this.$data);
      console.log("%c%s", "color:red","message: " + this.message)
    }
  }
</script>
(1)创建阶段

创建的标志点是New vue(),beforeCreate和created都发生在创建动作之后,但区别在于
beforeCreate触发的时候数据还没初始化和绑定,而created的时候就生成好了,具体我们看看console的内容:

创建阶段

数据很明显了,beforeCreate触发的时el、data都没初始化,但到created的时候虽然el依然没有初始化,但是data已经生成了,并且成功将message的值绑定上。

(2)挂载阶段

beforeMount和mounted两者主要区别在于模板是否编译和挂载了。


挂载阶段

el是用来告诉实例在那个元素上进行挂载的,我们可以看到beforeMount触发的时候el还是没有初始化,而到mounted的时候已经找到要挂载的元素,并且将模板编译了。

大家有没有发现,created和beforeMount的console内容一模一样?看到的时候我自己也疑惑了一下,那这样两个函数有什么区别?翻了一下网上一些文章,我发现他们的console结果和我不一样的:


网友console结果

如果根据这个结果分析的话,beforeMount触发的时候el已经初始化了,但是只是占了坑,挂上了编译前的模板。这和我的结果有挺大出入的,我也没找出是什么原因造成这样的结果差异,大家可以自己亲自试试,再对beforeMount这个函数下定义。

(3)更新阶段

加载页面的时候,其实到mounted这里就结束了,更新和销毁并不会触发到。
这里我另外写了一个方法去改变message的值,触发更新:

 methods:{
      change(){
        this.message = '不如更新一下咯'
      }
    },

控制台的结果:


更新阶段

我们可以看到,当我们去改变message的值的时候,触发了beforeUpdate函数,这个时候$el的值已经更改了,但是dom并没有变动。到update的时候,才真正去更新dom结构。

(4)销毁阶段

再写一个方法来触发销毁:

 methods:{
      destroy(){
        this.$destroy()
      }
    },

控制台的结果:


image.png

可以发现beforeDestory和destoryed打印出来的结果并没有什么特别,el的值data的数据依然在的。这是因为$destroy只是销毁一个实例,清理它与其它实例的连接,解绑它的全部指令及事件监听器,并不会清除data的数据或者清除dom。具体理解可参考:https://cn.vuejs.org/v2/api/#vm-destroy

相关文章

  • 初探Vue实例的生命周期

    Vue实例的生命周期简单地理解为8个钩子函数 Vue实例对每个钩子函数的调用时机如下 beforeCreate 在...

  • 一、vue基础知识点

    每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的: 实例生命周期钩子 每个 Vue 实例...

  • 深入浅出Vue生命周期钩子函数

    首先,先展示官方的Vue生命周期钩子函数的图示 在Vue2.0+版本,一个Vue实例共有以下八个生命周期钩子函数 ...

  • Vue生命周期

    Vue生命周期 实例生命周期钩子 每个Vue实例在被创建时都要经过一系列的初始化过程。 8种钩子函数 before...

  • vue02

    vue02 vue生命周期 1.0钩子函数: created -> 实例已经创建 √ beforeComp...

  • Vue入门系列(三)Vue实例的生命周期

    Vue实例生命周期钩子函数与React非常相似,最明显的区别在于,它多了一个实例创建阶段。 Vue实例和Vue组件...

  • VUE实例生命周期钩子

    1、vue实例生命周期钩子的由来 每个vue应用都是通过vue函数创建一个新的vue实例开始的: vue实例再被创...

  • 15.生命周期钩子

    Vue提供的生命周期钩子如下:①beforeCreate在实例被完全创建之后,触发这个钩子函数,此时data和ne...

  • vue生命周期

    学习vue的生命周期 什么是生命周期函数? vue的生命周期函数(又称为钩子函数)是一个vue实例从开始创建,到初...

  • vue 生命周期浅出

    官网生命周期图 Vue实例的生命周期: 挂载阶段: new Vue()调用构造函数 初始化生命周期钩子函数 调用t...

网友评论

    本文标题:理解vue实例的生命周期和钩子函数

    本文链接:https://www.haomeiwen.com/subject/chlxyftx.html