Vue生命周期
Vue生命周期:每个Vue实例被创建前都需要经过一系列的初始化过程,这个过程就是Vue的生命周期
在整个生命周期中会有很多钩子函数被提供,以便在Vue生命周期的不同时刻进行操作:
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>vue生命周期学习</title> <script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script> </head> <body> <!-- <div> <h1>id!=app的元素</h1> </div> --> <div id="app"> <h1>{{message}}</h1> </div> </body> <script> var vm = new Vue({ // el: '#app', // template: "<h1>{{message +'这是在template中的'}}</h1>", //在vue配置项中修改的 // render函数,优先级为render>template>id为app的外部HTML,同时存在将会覆盖 // render: function(createElement) { // return createElement('h1', 'this is render') // }, data: { message: 'Vue的生命周期' }, beforeCreate: function () { 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: function () { this.message = 'newVue的生命周期' 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: function () { console.group('------beforeMount状态------'); 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); //已被初始化 }, mounted: function () { 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: function () { console.group('beforeUpdate 状态===============》'); 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); // 直接通过dom节点拿到h1此时的值,发现没有被修改,只是修改了Vue中的message let dom = document.querySelector("h1").textContent; console.log(dom) }, updated: function () { console.group('updated 更新完成状态===============》'); 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); // 在updated阶段才将修改后的message渲染到HTML中 let dom = document.querySelector("h1").textContent; console.log(dom) }, beforeDestroy: function () { 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: function () { 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) } }) // 调用,从而将el挂载到Vue上 vm.$mount(this.$el = '#app') </script> </html>
在beforeCreate和created钩子函数之间的生命周期:
在这个生命周期之间,进行初始化事件,进行数据的观测,可以看到created的时候数据已经和data属性进行绑定,同时如果放在data中的属性的值发生改变时,视图也会改变,但是此时el仍然为undefined
在created和beforeMount间的生命周期:

首先会判断对象是否有el选项,有的话就继续向下编译,否则停止编译,即生命周期停止,直到在该Vue实例上调用vm.$mount(el)。
可以通过注释掉代码中的el:'#app'来看一下执行结果。结果显示程序只能执行到created函数
如果在该Vue实例后调用vm.$mount(this.$el = '#app'),(可以理解为将el = '#app'挂载到Vue实例对象上),则声明周期,即created之后的函数就可以继续执行
然后是template参数的有无对生命周期的影响
(1)如果Vue实例对象中有template选项,则将其作为模板编译成render函数
(2)如果没有,则将外部HTML作为模板编译
即template中的模板优先级要高于outer HTML的优先级,就是说内部template会将外部id=app的元素覆盖掉
这就是为什么el有无的判断要在template之前,因为template需要通过el来找到该Vue实例所控制的元素
Vue对象中还有一个render函数,它以createElement作为参数,执行页面渲染操作,可以直接在Vue对象中通过render写入HTML结构
beforeMount和mounted函数之间的生命周期:
可以在上图看到,此时是给Vue对象添加$el属性,并替换掉挂载的DOM元素。可见,程序输出的el由beforeMount之前的undefined变成了el : [object HTMLDivElement]
mounted生命周期:
可以在程序输出中看到,在beforeMount阶段,h1还是通过{{message}}进行占位的,因为此时还没有挂载到页面上,还是以JavaScript中的虚拟DOM形式存在的;而在mounted阶段,{{message}}被真正的数据替换掉
beforeUpdate和updated钩子函数之间的生命周期:
当Vue发现data中的数据发生了改变,会触发对应组件的重新渲染(re-render),先后调用beforeUpdate和updated钩子函数
注意,在beforeUpdate阶段,message的值已经被改变了,但是view层的数据并没有被重新渲染,仍然是原数据;而在updated阶段,才将更改的数据渲染到view层显示出来

beforeDestroy和destroyed钩子函数间的生命周期:
beforeDestroy钩子函数在实例销毁之前调用,在这一步,实例仍然完全可用
destroyed钩子函数在Vue实例销毁后调用,在销毁过程中,Vue实例指示的所有东西都会解除绑定,所有的时间监听器会被移除,所有的子实例也会被销毁