在vue实例开始创建、运行到销毁的过程,就是vue的生命周期
vue生命周期中发生(存在)的事件(这些事件可以用函数来表示),我们称之为生命周期钩子。
即:生命周期钩子=生命周期函数=生命周期事件。
我们看vue官网中存在着这么一张图片,详细的描述了vue的生命周期
1、开始阶段:
new Vue({})---------------------开始创建vue实例
Init events&Lifecycle--------此时的vue实例为空,什么都没有,只有默认的一些生命周期和 默认的事件,此时的data,methods,el等等都不存在,还没有初始 化数据
beforeCreate()钩子函数运行,但是此时的vue是一个空壳。我们尝试使用beforeCreate函数输出data和methods中的数据,看看会怎么样。
var vm=new Vue({
el:"#app",
data:{
msg:"hhh"
},
filters:{ //过滤器
},
directives:{ //自定义指令
},
methods:{ //方法
show:function () {
console.log("你好");
}
},
beforeCreate(){
console.log(this.msg);
this.show();
}
})
运行结果:
我们可以看到beforeCreate()钩子函数,输出data和methods中的数据时都显示未定义,可见得beforeCreate钩子函数在实例初始化数据之前,就被调用了。
1.1、初始化数据阶段:
init injections&reactivity--------------这个阶段的vue实例不再是空壳了,在它内部已经初始 化了数据和事件,包括data和methods,但是还没编译模板
created()钩子函数运行,此时你可以使用created钩子函数获取到vue中初始化的数据,在这里是你最早可以获取到数据的地方,可以更改数据而不会触update和其他的钩子函数。一般在这个钩子函数中进行初始化数据的获取。
var vm=new Vue({
el:"#app",
data:{
msg:"hhh"
},
filters:{ //过滤器
},
directives:{ //自定义指令
},
methods:{ //方法
show:function () {
console.log("你好");
}
},
/* beforeCreate(){ //这是第一个钩子函数运行在实例被完全创建之前,刚创建完一个空的vue实例就会触发beforeCreate函数
console.log(this.msg);
this.show();
}*/
created(){
console.log(this.msg);
this.show();
}
})
运行结果
created()钩子函数可以输出data和methods中的数据,证明数据已经在vue实例中初始化完毕。
1.2、编译模板阶段
从creatd()钩子函数到beforeMount钩子函数之间称之为编译模板阶段,此时模板编译成功,生成了一个编译好的模板字符串,在内存中将这个模板字符串渲染为内存中的DOM,但是还在内存中,没有挂载到页面中。
beforeMount钩子函数是可以在渲染前最后一次获取到vue中的数据,
<div id="app">
<h3 id="h3"></h3>
</div>
</body>
<script>
var vm=new Vue({
el:"#app",
data:{
msg:"hhh"
},
filters:{ //过滤器
},
directives:{ //自定义指令
},
methods:{ //方法
show:function () {
console.log("你好");
}
},
beforeMount(){
document.getElementById('h3').innerText="改变";
}
})
</script>
运行结果:
从上可以看到,我们在beforeMount()钩子函数中,更改页面上的h3元素内容,发现修改不成功,原因是beforeMount()钩子函数是触发在编译阶段的,此时还没搭载到页面上,就无法对页面上的元素和内容进行修改。
beforeMount()钩子函数,是位于编译模板阶段的钩子函数,在这里可以进行一般数据的获取和更改,同 created() 函数一样更改数据不会触发update和其他钩子函数,这个阶段是在内存中生成了虚拟DOM还没有挂载到页面中!!!
1.3、挂载(渲染真实DOM)页面阶段:
Create vm.$el and replace "el" with it-------之前是编译阶段,在内存中生成的是虚拟的DOM,还没挂载到页面上,编译模板阶段之后就是挂载阶段,此时在内存中的虚拟DOM挂载到了浏览器的页面上!!!我们可以操作页面上的DOM元素了!
mounted()钩子函数发生在此阶段,此时的vue实例已经被渲染到页面上,用户可以看到vue实例的页面,我们可以操作DOM等。
<div id="app">
<h3 id="h3"></h3>
</div>
</body>
<script>
var vm=new Vue({
el:"#app",
data:{
msg:"hhh"
},
filters:{ //过滤器
},
directives:{ //自定义指令
},
methods:{ //方法
show:function () {
console.log("你好");
}
},
mounted(){
document.getElementById('h3').innerText="我们在mounted中改变了真实的DOM";
}
})
</script>
运行结果:
mounted()钩子函数是实例在创建期间的最后一个钩子函数,它可以操作真实的DOM(它是最早可以操作DOM的函数),此时的实例已经被完全创建出来,如果我们对实例没有任何操作的话,那么这个实例就在内存中,什么也不发生。
2、运行阶段
在mounted()钩子函数之后,vue实例已经创建完毕了,此刻它就静静躺在内存中,进入到运行阶段。
这个运行阶段有两个钩子函数,只有当data中的数据发生改变时,才会触发。
当vue实例中的data改变时,它不是及时渲染到页面上的,而是在内存中对之前的虚拟DOM中的data数据进行更改,生成新的虚拟DOM之后才会挂载(渲染)到页面上,
beforeUpdate()钩子函数---------------更改data数据后,当虚拟DOM中的data发生改变时触发,此时 虚拟DOM没有加载到页面上。页面上的数据不变,虚拟DOM中 的数据改变。
<div id="app">
<h3 id="h3">{{ msg }}</h3>
<input type="button" value="提交" @click="show">
</div>
</body>
<script>
var vm=new Vue({
el:"#app",
data:{
msg:"原始的"
},
methods:{
show:function () {
this.msg="改变了";
console.log(this.msg);
}
},
beforeUpdate(){
console.log("获取页面上的msg"+document.getElementById('h3').innerText);
console.log("更改之后的msg"+this.msg);
}
})
</script>
运行截图
我们可以看到在beforeUpdate()钩子函数中,输出页面上h3的内容,输出的还是改变之前的msg,证明此函数只有在data中的数据发生改变,且新生成的虚拟DOM没有挂载(渲染)到页面上。
updated()钩子函数-----------------------更改data数据之后,虚拟DOM中的data发生改变页面上的data 也发生改变(即新生成的虚拟DOM挂载上页面了)
<div id="app">
<h3 id="h3">{{ msg }}</h3>
<input type="button" value="提交" @click="show">
</div>
</body>
<script>
var vm=new Vue({
el:"#app",
data:{
msg:"原始的"
},
methods:{
show:function () {
this.msg="改变了";
}
},
updated(){
console.log("获取页面上的msg:"+document.getElementById('h3').innerText);
console.log("更改之后的msg:"+this.msg);
}
})
</script>
运行结果:
可以看到,我们使用updated()钩子函数输出,页面的msg和data中的msg都是一致的,证明,updated()钩子函数的触发时条件是,data数据发生改变且虚拟DOM也挂载到了页面上。
3、销毁阶段
当用户关闭整个页面或者执行了某些$destroy时,就会从运行阶段进入销毁阶段(主要的一大特点是运行了beforeDestroy钩子函数)
销毁阶段有两个钩子函数:
beforeDestroy------------销毁前执行的钩子函数,可以继续使用vue实例中的数据,如data, methods,filters,derictives等等。
destroyed------------------已经销毁了,vue实例中的数据不可用了。