vue生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数。
附一张官网的生命周期图示
lifecycle.png
简单的来说,生命周期函数就是在某一个时间点会自动执行的函数。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>生命周期</title>
</head>
<body>
<div id="App">
<div>{{message}}</div>
</div>
<script src="js/vue.js"></script>
<script>
//生命周期函数就是在某一个时间点会自动执行的函数
var vm = new Vue({
el:"#App",
//template:"<div>{{message+'+template html'}}</div>",
data:{
message: "hello world"
},
//进行初始化事件,进行数据的观测,外部注入和双向绑定
beforeCreate:function(){
console.group('------beforeCreate创建前状态------');
console.log("el:"+this.$el);//undefined
console.log("data:"+this.$data);//undefined
console.log("message:"+this.message);//undefined
},
created:function(){
console.group('------created创建完毕状态------');
console.log("el:"+this.$el);//undefined
console.log("data:"+this.$data);//[object object]
console.log("message:"+this.message);//hello world
},
//vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。
beforeMount:function(){
console.group('------beforeMount挂载前状态------');
console.log("el:"+this.$el);//[object HTMLDivElement
console.log(this.$el);//<div id="App">...</div>
console.log("data:"+this.$data);//[object object]
console.log("message:"+this.message);//hello world
},
mounted:function(){
console.group('------mounted 挂载结束状态------');
console.log("el:"+this.$el);//[object HTMLDivElement
console.log(this.$el);//<div id="App">...</div>
console.log("data:"+this.$data);//[object object]
console.log("message:"+this.message);//hello world
},
beforeDestroy:function(){
console.log("beforeDestroy");
console.log("el:"+this.$el);
console.log(this.$el);
console.log("data:"+this.$data);
console.log("message:"+this.message)
},
destroyed:function(){
console.log("Destroy");
console.log("el:"+this.$el);
console.log(this.$el);
console.log("data:"+this.$data);
console.log("message:"+this.message)
},
beforeUpdate:function(){
console.log("beforeUpdate");
console.log("el:"+this.$el);
console.log(this.$el);
console.log("data:"+this.$data);
console.log("message:"+this.message)
},
updated:function(){
console.log("updated");
console.log("el:"+this.$el);
console.log(this.$el);
console.log("data:"+this.$data);
console.log("message:"+this.message)
}
})
</script>
</body>
</html>
运行结果.png
1. beforeCreate和created钩子函数
在dom创建vue实例,vue实例经过基础的初始化之后,就会自动调用beforeCreate函数,vue实例的挂载元素$el和数据对象data都为undefined。
之后vue会处理外部的注入和双向绑定相关的内容,这部分初始化也完成的时候,基本上vue实例的初始化操作都完成了,created函数被自动调用,数据已经和data属性进行绑定(放在data中的属性当值发生改变的同时,视图也会改变)
2. created钩子函数和beforeMount间的生命周期
首先会判断对象是否有el选项。如果有的话就继续向下编译,如果没有el选项,则停止编译,也就意味着停止了生命周期,直到在该vue实例上调用vm.$mount(el)。此时可以注释掉代码:el: '#app'
然后运行可以看到运行到created的时候就停止了
运行结果2
有el选项就紧接着询问实例上有无template选项
然后,我们往下看,template参数选项的有无对生命周期的影响。
(1)如果vue实例对象中有template参数选项,则将其作为模板编译成render函数。
(2)如果没有template选项,则将外部HTML作为模板编译。
(3)可以看到template中的模板优先级要高于outer HTML的优先级
<div id="App">
<div>{{message+'+outer html'}}</div>
</div>
<script>
//生命周期函数就是在某一个时间点会自动执行的函数
var vm = new Vue({
el:"#App",
template:"<div>{{message+'+template html'}}</div>",
data:{
message: "hello world"
}
})
执行后的结果在页面中显示
template.png
注释掉template这行显示
notemplate.png
然后,beforeCreate函数被自动调用,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。
3. beforeMount和mounted 钩子函数间的生命周期
beforeCreate函数执行完成之后,把结合数据生成的最终vue实例里面的dom元素挂载到页面上(vue实例对象添加$el成员,并且替换掉挂在的DOM元素),挂载到页面之上后,data.message成功渲染。
在beforeMount和mounted函数中分别打印this.$el显示如下
mounted.png
4. beforeDestroy和destroyed钩子函数
当vm.$destroy()被调用时,也就是要销毁这个组件,在组件即将被销毁时,beforeDestroy被执行,在组件被完全销毁之后,destroy被执行。
注:vm.$destroy()用法:完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。
destroyed.png
5. beforeUpdate和updated钩子函数
数据发生改变还没有重新渲染之前, beforeUpdate会执行,当重新渲染之后,updated会执行。
updated.png