定义:Vue实例或组件从创建到显示再到废弃的过程。
作用:给用户在不同阶段添加自己的代码的机会,更好的控制和使用实力。
生命周期图示:
代码示例:
<!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>生命周期示例</title>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
</head>
<body>
<div id="app">
<h1>{{message}}</h1>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
message: "生命周期示例"
},
beforeCreate: function() {
console.group('===beforeCreate创建前状态===');
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)
},
created: function() {
console.group('===created创建完毕状态===');
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);
},
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);
},
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);
},
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)
}
})
</script>
</html>
浏览器按F12快捷键查看控制台打印结果:

beforeCreate | 组件实例通过new Vue() 刚被创建,此时,数据data还未被挂载到vm对象,无法访问data和真实的dom挂载元素el,所以 $el,data都是undefined |
created | 组件实例创建完成,data已挂载,此时可更改data,一般可在此做数据初始化。此时DOM元素未生成,el不存在 |
beforeMount | 模板编译/挂载前,虚拟dom已经创建完成,未被渲染,此时改数据,不会触发其他钩子函数,可在此初始化数据 |
mounted | 模板编译/挂载后,组件已出现在页面中,数据、真实dom已处理好,事件已挂载好,可在此操作真实dom |
beforeUpdate | 组件更新前,当组件或实例的数据更改后,立即执行beforeUpdate,vue的虚拟dom机制重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿 |
updated | 数据完成更新、dom重渲染完成,可操作更新后的虚拟dom |
beforeDestroy | 组件销毁时立即执行beforeDestroy,可在此做善后工作,如清除计时器等 |
destroyed | 组件的数据绑定、监听...解绑后只剩dom空壳,此时,执行destroyed,在此做善后工作亦可 |
注意:
1. 在beforeMount期间:
我们发现el还是 {{message}},这里应用了 Virtual DOM
(虚拟Dom)技术,先占位,后续mounted
挂载时再把值渲染进去。
2. 在created和beforeMount期间:
(1) 首先会判断是否有el选项,如果有的话就继续向下编译,如果没有el选项,则停止编译,也就意味着停止了生命周期,直到在该实例上调用vm.$mount(el)[也就是动态引入了el]。现在,我们把代码中el配置注释掉,页面控制台如图2所示。

下面,我们在created钩子中继续调用vm.$mount(el),运行可见代码走完了,代码和效果如下图:
created: function() {
console.group('===created创建完毕状态===');
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);
this.$mount('#app')
},

(2) 在created期间,data数据已挂载,可操作data,但dom未生产,所以控制台上可见message数值,但是页面上的message未渲染,可与图一对比。
3. template配置项作用:
- 如果没有template选项,则将外部html作为模板编译(此示例便是)
- 如果如果vue实例对象中有template参数选项,则将其作为模板编译
- template中的模板优先级要高于outer html的优先级
现在我们来添加template参数,代码修改如下:
<body>
<div id="app">
<h1>{{message}}我是html</h1>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
template:"<h2>{{message}}我是模板,优先级高于外部html</h2>",
data: {
message: "生命周期示例"
},
})
...
</script>
浏览器按f12查看显示结果:

4.render函数:
vue对象中的render函数,以createElement为参数,然后做渲染。代码中添加render函数,效果如下图:
....
<body>
<div id="app">
<h1>{{message}}我是html</h1>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
template:"<h2>{{message}}我是模板,优先级高于外部html</h2>",
render:function(createElement){
return createElement('h2','我是render函数,我是老大')
},
data: {
message: "生命周期示例"
},
})
</script>

总结:优先级排序:render函数 > template选项 > outer Html
5. update钩子:
在chrome console里的输入命令:app.message = "单身狗"。可以看到,触发了beforeUpdate和updated钩子。updated函数中,数据已更改完成,dom已重新render,此时可操作更新后的虚拟dom。
tip:
以上,可看出,在mounted钩子中修改data会触发beforeUpdate,它之前的函数中只要不是可以跳出主线程的数据操作,都不会触发beforeUpdate。例如setTimeout会使代码跳出主线程到异步线程中,所以它的执行会在mounted之后,所以会触发beforeUpdate。
6.beforeDestroy和destroyed钩子函数:
在chrome console里的输入命令:app.$destroy()。浏览器显示如下。

beforeDestroy钩子在实例销毁之前执行。在这一步实例仍然可用。
destroyed钩子在Vue 实例销毁后执行。之后,Vue 实例指向的所有data解绑,事件监听器被移除,子实例被销毁。重点:$destory是解绑实例,不是删除实例,实例仍然存在。我们在控制台改变data的值,会发现页面并没有被渲染。
外带activated和deactivated钩子:
- activated:在组件被激活时调用,每次keep-alive激活时都会被被调用。
- deactivated:在组件被停用时调用。
本篇笔记就这么多,我是钱多多,一敲代码头就疼。