官方原图: img 上图中红色部分为常用的实例生命周期钩子,可以用在vue实例运行的各个阶段,按大概时间线:

先在例子中定义html元素:

1
2
3
<div id="app">
    <p id="myp">hehe{{a}}</p>
</div>
  • beforeCreate

    在vue实例创建前调用,此时属性方法都无法访问。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    new Vue({
        el: "#app",
        data:{
            a:"a"
        },
        methods:{
            hi(){
                console.log("hi");
            }
        },
        beforeCreate(){
            console.log("beforeCreate:a="+this.a);//beforeCreate:a=undefined
            console.log("beforeCreate:hi()=");//beforeCreate:hi()=
            this.hi();//报错
        }
    });
    
  • created

    在vue实例创建后,此时实例内定义的属性方法都可以访问到,但还没有进行渲染,无法访问$el属性

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    new Vue({
      el: "#app",
      data:{
          a:"aValue"
      },
      methods:{
          hi(){
              console.log("hi");
          }
      },
      created(){
          console.log("created:a="+this.a);//created:a=aValue
          console.log("created:hi()="+this.hi());//created:hi()=
          this.hi();//hi
          console.log(document.getElementById("myp").innerText);//hehe{{a}}
          console.log(this.$el);//undefined
      }
    });
    
  • beforeMount

    到这一步已经把template编译成了render,此时可以访问到$el的内容,但还没有挂载到页面(替换掉网页中的模板),

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    new Vue({
      el: "#app",
      data:{
          a:"aValue"
      },
      beforeMount(){
          console.log(this.$el);//div#app,展开以后有很多属性
          console.log(document.getElementById("myp").innerText);//hehe{{a}}
      }
    });
    
  • mounted

    此时渲染好的内容已经挂载到网页上,所有创建工作完成

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    new Vue({
      el: "#app",
      data:{
          a:"aValue"
      },
      mounted(){
          console.log(document.getElementById("myp").innerText);//heheaValue
      }
    });
    
  • beforeUpdate

    这个状态对应数据已经变更,但页面没有重新渲染之前,可以在虚拟dom中访问更新之前的dom元素值,但此时变量已经为新值

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    new Vue({
        el: "#app",
        data:{
            a:"aValue"
        },
        beforeUpdate(){
            //在浏览器vue devtool中修改a的值为newvalue
            console.log("beforeUpdate:a="+this.a);//beforeUpdate:a=newvalue
            //beforeUpdate:a-dom=heheaValue
            console.log("beforeUpdate:a-dom="+document.getElementById("myp").innerText);
        }
    });
    
  • updated

    此时更新后虚拟dom已经重新渲染,官方文档建议不要在此期间更改状态,用计算属性watcher取代。

    如下面的例子,在update()函数内部加入this.$data.a=this.$data.a+"a",会导致页面无限循环渲染。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    new Vue({
      el: "#app",
      data:{
          a:"aValue"
      },
      updated(){
          //在浏览器vue devtool中修改a的值为newvalue
          //bupdated:a-dom=hehenewvalue
          //this.$data.a=this.$data.a+"a"//加入此行会无限循环渲染
          console.log("updated:a-dom="+document.getElementById("myp").innerText);
      }
    });
    
  • beforeDestroydestroyed

    beforeDestroyed这个状态下可以访问vue实例,所有跟销毁有关的操作应该在这里完成。

    destroyed这个状态下仍然可以访问虚拟dom,但实例已经完全销毁,可以看源码*/src/core/instance/lifecyle.js得知,触发$destroy时,先执行beforeDestroy勾子,再执行具体销毁过程,最后调用destroyed勾子,也就是说,在destroyed勾子里对实例进行任何操作都没有意义了。