Vue.js从入门到项目实践(超值版)
上QQ阅读APP看书,第一时间看更新

2.4 实例的生命周期

本节将介绍Vue实例从创建、运行到销毁的整个过程。在Vue实例的创建、运行、销毁期间,总是伴随着各种各样的事件,这些事件统称为“生命周期”。下面通过案例对生命周期进行详解。

Vue实例的生命周期代码如下:

1.beforeCreate()

beforeCreate()在实例初始化后,数据观测(data observer)和event/watcher事件配置前被调用。

提示:这个时候this还不能使用,data中的数据、methods中的方法,以及watcher中的事件都不能获得,值为undefined。

代码如下:

运行的结果如图2-14所示。

图2-14 beforeCreate()运行结果

2.created()

created()在实例已经创建完成后被调用。在这一步,实例已完成以下配置:数据观测(data observer)、属性和方法的运算及watch/event事件回调。挂载阶段还没开始的$el属性为不可见,值为undefined。

提示:这个时候可以操作Vue中的数据和方法,但是还不能对DOM节点进行操作。

    created(){
       console.group('created 创建完毕状态');
       console.log("%c%s", "color:red", "el      : "+this.$el);         //undefined
       console.log("%c%s", "color:red", "data    : "+this.$data);       //[object Object]
       console.log("%c%s", "color:red", "message : "+this.message);     //值为Hello World!!!
    },

运行的结果图如图2-15所示。

图2-15 created()运行结果

3.beforeMount()

beforeMount()在挂载开始前被调用,相关的render函数首次被调用。

提示:这个时候,$el属性已存在,是虚拟DOM,只是数据未挂载到模板中。

    beforeMount(){
      console.group('beforeMount 挂载前状态');
      console.log("%c%s", "color:red", "el      : "+this.$el);      //[object HTMLDivElement]
      console.log(this.$el);
      console.log("%c%s", "color:red", "data    : "+this.$data);    //[object Object]
      console.log("%c%s", "color:red", "message : "+this.message);  //值为Hello World!!!
    },

运行的结果如图2-16所示。

图2-16 beforeMount()运行结果

4.mounted()

el被新创建的vm.$el替换,并挂载到实例上后调用该钩子函数。如果root实例挂载了一个文档内元素,当mounted()被调用时vm.$el也在文档内。mounted()不会承诺所有的子组件都一起被挂载。如果想要整个视图都渲染完毕,可以使用vm.$nextTick替换mounted()。

提示:挂载完毕,这时DOM节点被渲染到文档内,DOM操作在此时能正常进行。

    mounted(){
       console.group('mounted 挂载结束状态');
       console.log("%c%s", "color:red", "el     : "+this.$el);      //[object HTMLDivElement]
       console.log(this.$el);
       console.log("%c%s", "color:red", "data   : "+this.$data);    //[object Object]
      console.log("%c%s", "color:red", "message : "+this.message);  //值为Hello World!!!
    },

运行的结果如图2-17所示。

图2-17 mounted()运行结果

5.beforeUpdate()

beforeUpdate()在数据更新时被调用,发生在虚拟DOM打补丁前。这里适合在更新前访问现有的DOM,例如手动移除已添加的事件监听器。

提示:beforeUpdate()是指View层的数据变化前,而不是data中的数据改变前被触发。因为Vue是由数据驱动的。

    beforeUpdate(){
      console.group('beforeUpdate 更新前状态');
      console.log("%c%s", "color:red", "el      : "+this.$el);      //[object HTMLDivElement]
      console.log(this.$el);
      console.log(this.$el.innerHTML);
      console.log("%c%s", "color:red", "data    : "+this.$data);    //[object Object]
      console.log("%c%s", "color:red", "message : "+this.message);  //值为Hello Vue!!!
    },

运行的结果如图2-18所示。

图2-18 beforeUpdate()运行后修改message值为Hello Vue!!!

6.updated()

由于数据的更改导致虚拟DOM重新渲染和打补丁,在这以后会调用该钩子函数。当该钩子函数被调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而,在大多数情况下,应该避免在此期间更改状态。如果要改变相应状态,最好使用计算属性或watcher取而代之。updated()不会承诺所有的子组件都一起被重绘。如果希望等到整个视图都重绘完毕,可以用vm.$nextTick替换掉updated()。

提示:View层的数据更新后,data中的数据同beforeUpdate(),都是更新完以后的。

    updated(){
       console.group('updated 更新完成状态');
       console.log("%c%s", "color:red", "el      : "+this.$el);      //[object HTMLDivElement]
       console.log(this.$el);
       console.log(this.$el.innerHTML);
       console.log("%c%s", "color:red", "data    : "+this.$data);    //[object Object]
       console.log("%c%s", "color:red", "message : "+this.message);  //值为Hello Vue!!!
    },

运行的结果如图2-19所示。

图2-19 updated()运行结果

提示:从上面可以看到,beforeUpdate()和updated()钩子函数中的$el一样,因为beforeUpdate()应该指向虚拟DOM,所以$el才会相同,而DOM中的真正内容是不一样的。

7.beforeDestroy()

beforeDestroy()在实例销毁前被调用。在这一步,实例仍然完全可用。

提示:执行vm.$destroy()触发beforeDestroy()和destoryed()钩子函数。

    beforeDestroy(){
       console.group('beforeDestroy 销毁前状态');
       console.log("%c%s", "color:red", "el      : "+this.$el);       //[object HTMLDivElement]
       console.log(this.$el);
       console.log("%c%s", "color:red", "data    : "+this.$data);     //[object Object]
       console.log("%c%s", "color:red", "message : "+this.message);   //值为Hello Vue!!!
    },
8.destroyed()

destroyed()在Vue实例销毁后被调用。调用后,Vue实例指向的所有部分都会被解绑定、所有的事件监听器会被移除、所有的子实例也会被销毁。

提示:执行destroyed ()后,对data的改变不会再触发生命周期函数,此时的Vue实例已经解除了事件监听及与DOM的绑定,但是DOM结构依然存在。

    destroyed(){
      console.group('destroyed 销毁完成状态');
      console.log("%c%s", "color:red", "el      : "+this.$el);      //[object HTMLDivElement]
      console.log(this.$el);
      console.log("%c%s", "color:red", "data    : "+this.$data);    //[object Object]
      console.log("%c%s", "color:red", "message : "+this.message);  //值为Hello Vue!!!
    },