Vue的生命周期详解

一. 官方的生命周期图与对应解释

在这里插入图片描述

在这里插入图片描述

二.实例生命周期钩子详解

我用两个组件切换来展示组件各个生命周期钩子的调用时间。
并在两个组件内设置修改data值的函数,以便构成更新后的钩子调用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://unpkg.com/vue/dist/vue.js"></script>
		<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
	</head>
	<body>
		<div id="app">
			<router-link to="/bar">bar</router-link><br/><br/>
			<router-link to="/foo">foo</router-link><br/><br/>
			<router-view/>
		</div>
		
		<script type="text/javascript">

			var bar = {
				template: '<div><button @click="changeBar">修改bar的data</button><br/><br/><p>bar组件---{{message}}</p></div>',
				data() {
					return {
						message:'I am bar '
					}
				},
				methods: {
					changeBar() {
						this.message = 'change  bar !!!'
					}
				},
				beforeCreate: function () {
				         console.group('bar组件的   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 () {
				     console.group('bar组件的   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('bar组件的   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('bar组件的   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('bar组件的   beforeUpdate 更新前状态===============》');
				     console.log("%c%s", "color:red","el     : " + this.$el);
				     console.log(this.$el.innerHTML);   
				        console.log("%c%s", "color:red","data   : " + this.$data); 
				        console.log("%c%s", "color:red","message: " + this.message); 
				 },
				 updated: function () {
				     console.group('bar组件的   updated 更新完成状态===============》');
				     console.log("%c%s", "color:red","el     : " + this.$el);
				     console.log(this.$el.innerHTML); 
				        console.log("%c%s", "color:red","data   : " + this.$data); 
				        console.log("%c%s", "color:red","message: " + this.message); 
				 },
				 beforeDestroy: function () {
				     console.group('bar组件的   beforeDestroy 销毁前状态===============》');
				     console.log("%c%s", "color:red","el     : " + (this.$el));
				     console.log(this.$el.innerHTML); 
				        console.log("%c%s", "color:red","data   : " + this.$data); 
				        console.log("%c%s", "color:red","message: " + this.message); 
				 },
				 destroyed: function () {
				     console.group('bar组件的   destroyed 销毁完成状态===============》');
				     console.log("%c%s", "color:red","el     : " + (this.$el));
				     console.log(this.$el.innerHTML); 
				        console.log("%c%s", "color:red","data   : " + this.$data); 
				        console.log("%c%s", "color:red","message: " + this.message)
				 }
			}
			
			
			var foo = {
				template: '<div><button @click="changeFoo">修改Foo的data</button><br/><br/><p>foo组件---{{message}}</p></div>',
				data() {
					return {
						message:'I am foo '
					}
				},
				methods: {
					changeFoo() {
						this.message = 'change  foo !!!'
					}
				},
				beforeCreate: function () {
				         console.group('foo组件的  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 () {
				     console.group('foo组件的  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('foo组件的  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('foo组件的  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('foo组件的  beforeUpdate 更新前状态===============》');
				     console.log("%c%s", "color:red","el     : " + this.$el);
				     console.log(this.$el.innerHTML);  
				        console.log("%c%s", "color:red","data   : " + this.$data); 
				        console.log("%c%s", "color:red","message: " + this.message); 
				 },
				 updated: function () {
				     console.group('foo组件的  updated 更新完成状态===============》');
				     console.log("%c%s", "color:red","el     : " + this.$el);
				     console.log(this.$el.innerHTML); 
				        console.log("%c%s", "color:red","data   : " + this.$data); 
				        console.log("%c%s", "color:red","message: " + this.message); 
				 },
				 beforeDestroy: function () {
				     console.group('foo组件的  beforeDestroy 销毁前状态===============》');
				     console.log("%c%s", "color:red","el     : " + this.$el);
				     console.log(this.$el.innerHTML);  
				        console.log("%c%s", "color:red","data   : " + this.$data); 
				        console.log("%c%s", "color:red","message: " + this.message); 
				 },
				 destroyed: function () {
				     console.group('foo组件的  destroyed 销毁完成状态===============》');
				     console.log("%c%s", "color:red","el     : " + this.$el);
				     console.log(this.$el.innerHTML); 
				        console.log("%c%s", "color:red","data   : " + this.$data); 
				        console.log("%c%s", "color:red","message: " + this.message)
				 }
			}
			
			const router = new VueRouter({
				routes: [
					{
						path:'/foo',
						component:foo
					},
					{
						path:'/bar',
						component:bar
					}
				],
			})
			const vm = new Vue({
				el: '#app',
				router	
			})
		</script>
	</body>
</html>

效果如下,此时还没有进入子组件,所以还没有调用生命周期钩子,因为我没有在父组件上使用生命周期钩子,所以控制台还是空

在这里插入图片描述

1.beforeCreate和created

由上图可知,beforeCreate是在组件实例刚刚创建时调用的,这时组件内的属性全都没有计算,
如data,还有DOM也没有生成,所以$el也不存在($el就是对应组件的DOM结构,<div></div>
之类的)
created则是在组件实例创建后调用的,此时组件内的属性如data就已经被初始化了,
data属性内的值也被初始化了,但是由于DOM结构还没有渲染,使用$el还是不存在

在这里插入图片描述

2.beforeMount和mounted

beforeMount:
是在组件挂载之前调用的,什么是挂载呢?其实就是组件DOM结构出现在页面上,
beforeMount执行的时候DOM结构还没出现在页面上,所以不能获取this.$el
mounted:
执行的时候,此时页面就加载出来了,DOM结构出现在了页面上,this.$el也就
可以拿到DOM结构了

在这里插入图片描述

3.beforeUpdate 和 updated

beforeUpdate :
是在组件更新之前调用的,此时的状态还是更新前的状态,比如data里面的值还是之前的值
updated:
是在组件更新之后调用的,此时状态已经是更新后的状态了

我用this.$el.innerHTML来展示内部的html代码,为什么不和前面一样直接使用this.$el
拿到DOM结构再来看有没有什么不同呢?因为this.$el 是一个对象,相当于一个指针,因此
当你使用 console.log 输出之后,其内容并没有真正显示,而当你点开下面的箭头展开具体
内容时,显示的是该指针指向对象的当前内容,所以无法判断更新前后的变化,而使用
this.$el.innerHTML可以直接获取DOM结构的html代码,便于我们观察更新前后的变化

在这里插入图片描述

4.beforeDestroy 和destroyed

beforeDestroy :
是在组件被销毁前调用的,什么是销毁呢?简单来说就是组件切换时,上一个组件就被销毁了
destroyed:
是组件销毁后调用的

在这里插入图片描述
可以看到,组件销毁是在另一个之前挂载到页面后和挂载到页面前中间,即 beforeMount和mounted 钩子调用之间调用的

总结:
一般情况我们获取数据而且是不涉及DOM操作的请求我们放在created()里面,因为此时组件内部的属性已经存在,可以进行取值与赋值,但是如果涉及DOM操作就要放在mounted()里面了,不然获取不到DOM元素,其他钩子用的相对较少,但是我相信学到后面会慢慢清除他们的用处,到时肯定有所收益

参考文献:
https://segmentfault.com/a/1190000008010666?utm_source=tag-newest
通过上面那位老哥对生命周期钩子的解释再进行的分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值