生命周期
生命周期函数就是 Vue 实例在某一个时间点会自动执行的函数。
简单来说就是好像把人的出生到死亡分成一个个阶段,你取名字肯定是在你出生阶段,而不是在成年阶段;你结婚肯定是在成年阶段,而不是在出生阶段;如果说你在出生阶段想去阶段,那肯定是不行的。
组件也是一样,在实例化的时特定阶段调用特定方法,调用的这个方法就是钩子函数。
钩子函数
钩子函数和回调函数有什么区别吗?
它们区别是:
js
派函数监听事件 => 监听函数就是所谓的钩子函数 => 函数钩取事件:函数主动找事件 => 钩子函数
js
预留函数给dom
事件,dom
事件调用js
预留的函数 => 事件派发给函数:事件调用函数 => 回调函数
打个比方:
钩子函数:一个房间里的监控摄像头监控着每一个进入的人的面部特征,识别出了符合条件的人就触发警告(执行函数事件);回调函数:可以看做是在一片地区埋了许许多多的地雷,一旦踩中了某个地雷(触发事件),地雷就会爆炸(执行函数事件)。
可以简单的理解为:
钩子函数是事件被动的监听,一旦条件触发就执行回调函数是主动事件,执行函数体内容
生命周期探究
<template>
<div>{{msg}}</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'hello world',
msg1: ''
}
},
beforeCreate () {
console.groupCollapsed('beforeCreate 创建前状态')
console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el)
console.log(this.$el)
console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data)
console.log(this.$data)
console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
console.groupEnd()
},
created () {
console.groupCollapsed('created 创建前状态')
console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el)
console.log(this.$el)
console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data)
console.log(this.$data.msg)
console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
console.groupEnd()
},
beforeMount () {
console.groupCollapsed('beforeMount 挂载前状态')
console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el)
console.log(this.$el)
console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data)
console.log(this.$data.msg)
console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
console.groupEnd()
},
mounted () {
console.groupCollapsed('mounted 挂载后状态')
console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el)
console.log(this.$el)
console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data)
console.log(this.$data.msg)
console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
console.groupEnd()
setTimeout(() => {
this.$data.msg = '123'
}, 5000)
},
activated () {
console.groupCollapsed('activated 挂载后状态')
console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el)
console.log(this.$el)
console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data)
console.log(this.$data.msg)
console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
console.groupEnd()
setTimeout(() => {
this.$data.msg = 'hello tiantian'
}, 10000)
},
beforeUpdate () {
console.groupCollapsed('beforeUpdate 更新前状态')
console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el)
console.log(this.$el)
console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data)
console.log(document.getElementById('app').innerHTML)
console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
console.groupEnd()
},
updated () {
console.groupCollapsed('updated 更新后状态')
console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el)
console.log(this.$el)
console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data)
console.log(document.getElementById('app').innerHTML)
console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
console.groupEnd()
setTimeout(() => {
this.$destroy()
}, 5000)
},
beforeDestroy () {
console.groupCollapsed('beforeDestroy 实例销毁前状态')
console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el)
console.log(this.$el)
console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data)
console.log(document.getElementById('app').innerHTML)
console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
console.groupEnd()
},
destroyed () {
console.groupCollapsed('destroyed 实例销毁后状态')
console.log('%c%s', 'color:MediumVioletRed', 'el : ' + this.$el)
console.log(this.$el)
console.log('%c%s', 'color:MediumVioletRed', 'data : ' + this.$data)
console.log(document.getElementById('app').innerHTML)
console.log('%c%s', 'color:MediumVioletRed', 'msg: ' + this.msg)
console.groupEnd()
}
}
</script>
beforeCreate
和created
beforeCreate
:在实例初始化完成时,被执行
created
:在初始化结束之后会再初始化一些外部注入和一些双向绑定相关的事情时,被执行
这两个钩子函数执行完之后,初始化基本完成了。
在beforeCreate
阶段,el
和data
都没有被挂载;而在created
阶段,el
还没被挂在,但data
已经被挂载了,如下图所示:
这里el
为啥没有被挂载呢?
看上图,在created
执行完毕后,它会询问一个条件:你这个Vue
实例里是否有el
这个选项。
如果有就又会询问是否有template
这个选项:
-
如果没有
template
就会走右侧的分支,- 如果这个实例没有
template
,就会将el
这个根节点当做模版,来进行渲染
- 如果这个实例没有
-
如果有
template
就会走左侧的分支- 把
template
作为模版去渲染
- 把
beforeMount
和mounted
beforeMount
:执行时,页面还没有被渲染mounted
:执行时,页面已经被渲染了
从图中也可以看出,在beforeMount
执行时,el
还没有被挂在;当mounted
执行时,el
被挂载到页面了。
beforeUpdate
和updated
beforeUpdate
:数据被改变,还没渲染之前会被执行
updated
:数据被改变,渲染完成后会被执行
这张图中有个奇怪的现象,为什么在beforeUpdate
和updated
两个钩子函数中,el
和msg
都是一样呢?beforeUpdate
执行是不应该是老数据嘛,怎么这里也是最新的数据了?
因为这里的el
是虚拟dom
,不是真实的dom
,和data
都是对象,在加上console.log
这里是个异步操作,当你点开console.log
时,其实代码早就跑完了,数据已经是最新的了,所以就会看到在这两个函数中输出结果是一样的了。
可以用document.getElementById('app').innerHTML
获取真实的Dom
结构,这时我们就可以看到这两处不一样的地方了。
beforeDestroy
和destroyed
调用vm.$destroy()
方法可对实例销毁
beforeDestroy
:实例被销毁前被执行
destroyed
:实例被销毁后被执行
activated
和deactivated
使用keep-alive
标签后,会有两个生命周期函数分别是:activated
、deactivated
activated
:页面展示的时候被执行
deactivated
:页面被隐藏或者页面即将被替换成新的页面时被执行
总结
created
:挂载之前需要做的一些事情可以在放在这里面,比如页面加载时loading
动画
mounted
:向后端发请求,可以放在这个函数中。
这两个钩子函数使用时机重叠部分很多,反正是怎么方便怎么来就是了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。