Vue中的生命周期和钩子函数
首先,先给大家看一张图,这张图清晰的给出了Vue中每一个Vue实例被创建前的初始化过程。接下来,我就给大家逐个进行讲解。
下面我们从源码方面详细解释一下这张图
1.实例化
显而易见,这个就是实例化。实例化之后,会执行以下操作。根据Vue的源码,我们可以看到Vue的本质就是一个
function
,new Vue
的过程就是初始化参数、生命周期、事件等一系列过程。
2.初始化事件 生命周期函数
首先就是初始化事件和生命周期函数。这时候,这个对象身上只有默认一些生命周期函数和默认的事件,其他的东西都未创建。
3.beforeCreate:Vue实例创建前
接着就是beforeCreate(创建前)
执行。但是这个时候拿不到data
里边的数据。data
和methods
中的数据都还没初始化。
4.注射响应
injections(注射器)reactivity(响应)
给数据添加观察者。
5.created:Vue实例创建后(请求数据)
created创建后
执行。因为上边给数据添加了观察者,所以现在就可以访问到data
中的数据了。这个钩子也是常用的,可以请求数据了。如果要调用methods
中的方法或者操作data
中的数据,要在created
里操作。又因为请求数据是异步的,所以发送请求宜早不宜迟,通常在这个时候发送请求。
6.是否存在el(元素)
el
指明挂载目标。这个步骤就是判断一下是否有写el
,如果没有就判断有没有调用实例上的$mount(")
方法调用。也就是下一张图。
7.判断是否有template
判断是否有template
。
- 如果有
template
则渲染template
里面的内容。
- 如果没有则渲染
el
指明的挂载对象里的内容。
8.beforeMount:Vue实例挂载前
beforeMount挂载前
执行。
9.替换el
这个时候会在实例上创建一个el
,替换掉原来的el
。也就是真正的挂载。
10.mounted:Vue实例挂载后(可以操作DOM元素)
mounted挂载后
执行。这个时候DOM
已经加载完成了,可以操作DOM
了。只要执行完了mounted
,就表示整个Vue实例已经初始化完毕了。这个也是常用的钩子。一般操作DOM
都是在这里。
11.dataChange
当数据有变动时,会触发下面这个两个钩子函数。
-
在
beforeUpdate更新前
和update更新后
之间会进行DOM
的重新渲染和补全。
-
接着是update更新后
12.callDestroy
-
beforeDestroy销毁前
和destroy销毁后
这两个钩子是需要我们手动调用实例上的$destroy
方法才会触发的。 -
当
$destroy
方法调用后。 -
beforeDestroy销毁前
触发。
-
移除数据劫持、事件监听、子组件属性所有的东西还可以保留只是不能修改。
-
destroy销毁后
触发。
新增钩子:
- activated:keep-alive组件激活时调用。类似created没有真正创建,只是激活。
- deactivated:keep-alive组件停用时调用。类似destroyed没有真正移除,只是禁用。
- 在2.2.0及其更高版本中,activated和deactivated将会在树内的所有嵌套组件中触发。
<body>
<div id="app">
{{msg}}
</div>
<script>
let vm = new Vue({
el:"#app", // 指明 VUE实例 的挂载目标 (只在 new 创建的实例中遵守)
data:{msg:"kaikeba"},
beforeCreate() {
console.log('创建前')
},
created() {
console.log('创建后')
},
beforeMount() {
console.log('挂载前')
},
mounted() {
console.log('挂载后')
},
beforeUpdate() {
alert('更新前')
},
updated() {
alert('更新后')
},
beforeDestroy() {
alert('销毁前')
},
destroyed() {
alert('销毁后')
},
})
option // vm.$mount('#app') // 等价于 el:"#app"
vm.$destroy() // init events, init lifecycle 初始事件,初始化生命周期钩子函数
// init injections (注射器) reactivity (响应) 给数据添加观察者
// Compile el's outerHTML as template 编译el的outerHTML作为模板
// 在beforeMount mounted 之间 create vm.$el and replace “el” with it 会创 建一个 el 代替自己的el对象
// virtual DOM re-render and patch 虚拟DOM重新渲染和修补
// when vm.$destroy() is called 当销毁函数vm.$destroy()调用时 才会调用销毁前 后的生命周期
// teardown watchs child components and event listeners 移除数据劫持、事件 监听、子组件属性 所有的东西还保留 只是不能修改
</script>
</body>
总结:
1.beforeCreate:在实例初始化之后,数据观测(data observe)和event/watcher
事件配置之前被调用,这时无法访问data
及props
等数据;
2.created:在实例创建完成后被立即调用,此时实例已完成数据观测(data observe),属性和方法的运算,watch/event
事件回调,挂载阶段还没开始,$el
尚不可用。
3.beforeMount:在挂载开始之前被调用,相关的render
函数首次被调用。
4.mounted:实例被挂载后调用,这时el
被新创建的vm.$el
替换,若根实例挂载到了文档上的元素上,当mounted
被调用时vm.$el
也在文档内。注意mounted
不会保证所有子组件一起挂载。
5.beforeUpdate:数据更新时调用,发生在虚拟DOM
打补丁前,这时适合在更新前访问现有DOM
,如手动移除已添加的事件监听器。
6.updated:在数据变更导致的虚拟DOM
重新渲染和打补丁后,调用的钩子函数。当这个钩子函数被调用时,组件DOM
已更新,可执行依赖于DOM
的操作。多数情况下应在此期间更改状态。如需改变,最好使用watcher
或者计算属性computed
取代。注意:updated
不会保证所有的子组件都能一起呗重绘。
7.beforeDestroy:在实例销毁之前调用。在这时,实例仍可用。
8.destroyed:实例销毁后调用。这时Vue实例的所有指令都被解绑,所有事件监听器被移除,所有子实例也被销毁。