vue2.x生命周期
- 事物从出生到死亡的过程
- 每个
Vue
实例在被创建时都要经过一系列的初始化过程,例如:需要设置数据的监听,编译模板,将实例挂载到DOM
上,并且在数据变化时更新DOM
等,这些过程统称为Vue
实例的生命周期
。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
####常用的 钩子函数
beforeCreate | 在实例初始化之后,数据观测和事件配置之前被调用 此时data 和 methods 以及页面的DOM结构都没有初始化 什么都做不了 |
---|---|
created | 在实例创建完成后被立即调用此时data 和 methods已经可以使用 但是页面还没有渲染出来 |
beforeMount | 在挂载开始之前被调用 此时页面上还看不到真实数据 只是一个模板页面而已 |
mounted | el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。 数据已经真实渲染到页面上 在这个钩子函数里面我们可以使用一些第三方的插件 |
beforeUpdate | 数据更新时调用,发生在虚拟DOM打补丁之前。 页面上数据还是旧的 |
updated | 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。 页面上数据已经替换成最新的 |
beforeDestroy | 实例销毁之前调用 |
destroyed | 实例销毁后调用 |
其实Vue
实例的生命周期,主要分为三个阶段,分别为
-
挂载(初始化相关属性,例如
watch
属性,method
属性)beforeCreate
created
beforeMount
mounted
-
更新(元素或组件的变更操作)
beforeUpdate
updated
-
销毁(销毁相关属性)
beforeDestroy
destroyed
下面,我们来看一道面试题:
关于Vue的生命周期,下列哪项是不正确的?()[单选题] A、Vue 实例从创建到销毁的过程,就是生命周期。 B、页面首次加载会触发beforeCreate, created, beforeMount, mounted, beforeUpdate, updated。 C、created表示完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来。 D、DOM渲染在mounted中就已经完成了。
一个案例让你了解什么是生命周期。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<div>{{msg}}</div>
<button @click.number='update(5)'>更新</button>
<button @click='destroy'>销毁</button>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
Vue实例的生命周期
*/
var vm = new Vue({
el: '#app',
data: {
msg: 0
},
template:"<h1>我是模板</h1>",
methods: {
update: function(num){
this.msg += num;
},
destroy: function(){
this.$destroy();
}
},
beforeCreate: function(){
console.log('beforeCreate');
},
created: function(){
console.log('created');
},
beforeMount: function(){
console.log('beforeMount');
},
mounted: function(){
console.log('mounted');
},
beforeUpdate: function(){
console.log('beforeUpdate');
},
updated: function(){
console.log('updated');
},
beforeDestroy: function(){
console.log('beforeDestroy');
},
destroyed: function(){
console.log('destroyed');
}
});
// vm.$mount("#app");//添加了$mount方法
</script>
</body>
</html>
beforeCreate
: Vue
实例初始化之后,以及事件初始化,以及组件的父子关系确定后执行该钩子函数,一般在开发中很少使用。
created
: 在调用该方法之前,初始化会被使用到的状态,状态包括props
,methods
,data
,computed
,watch
.
而且会实现对data
中属性的监听,也就是在created
的时候数据已经和data
属性进行了绑定。(放在data
中的属性当值发生改变的时候,视图也会改变)。同时也会对传递到组件中的数据进行校验。
所以在执行created
的时候,所有的状态都初始化完成,我们也完全可以在该阶段发送异步的ajax
请求,获取数据。
但是,在created
方法中,是无法获取到对应的的$el
选项,也就是无法获取Dom
. 所以说上题中选项c
的说法是正确的
created
方法执行完毕后,下面会判断对象中有没有el
选项。如果有,继续执行下面的流程,也就是判断是否有template
选项,如果没有el
选项,则停止整个生命周期的流程,直到执行了vm.$mount(el)
后,才会继续向下执行生命周期的流程。
我们将上方代码el
选项去掉了,运行上面的代码后,我们发现执行完created
方法后,整个流程就停止了。
现在,我们不添加el
选项,但是手动执行vm.$mount(el)
,也能够使暂停的生命周期进行下去。
我们继续向下看,就是判断在对象中是否有template
选项。
第一:如果Vue
实例对象中有template
参数选项,则将其作为模板编译成render
函数,来完成渲染。
第二:如果没有template
参数选项,则将外部的HTML作
为模板编译(template
),也就是说,template
参数选项的优先级要比外部的HTML
高
第三:如果第一条,第二条件都不具备,则报错。
接下来会触发beforeMount
这个钩子函数:
在执行该钩子函数的时候,虚拟DOM
已经创建完成,马上就要渲染了,在这里可以更改data
中的数据,不会触发updated
, 其实在created
中也是可以更改数据,但是不会触发updated
函数。
下面再执行mounted
的时候,可以看到真实的数据。同时整个组件内容已经挂载到页面中了,数据以及真实DOM
都已经处理好了,可以在这里操作真实DOM
了,也就是在mounted
的时候,页面已经被渲染完毕了,在这个钩子函数中,我们可以去发送ajax
请求。
当整个组件挂载完成后,有可能会进行数据的修改,当Vue
发现data
中的数据发生了变化,会触发对应组件的重新渲染,先后调用了beforeUpdate
和updated
钩子函数。
在updated
之前beoreUpdate
之后有一个非常重要的操作就是虚拟DOM
会重新构建,也就是新构建的虚拟DOM
与上一次的虚拟DOM
树利用diff
算法进行对比之后重新渲染。
而到了updated
这个方法,就表示数据已经更新完成,dom
也重新render
完成。
下面如果我们调用了vm.$destroy
方法后,就会销毁所有的资源。
首先会执行beforeDestroy
这个钩子函数,这个钩子函数在实例销毁前调用,在这一步,实例仍然可用。
在该方法中,可以做一些清理的工作,例如:清除定时器等。
但是执行到destroyed
钩子函数的时候,Vue
实例已经被销毁,所有的事件监听器会被移除,所有的子实例也会被销毁。
最后做一个简单的总结:
beforeCreate( )// 该钩子函数执行时,组件实例还未创建.
created()//组件初始化完毕,各种数据可以使用,可以使用ajax发送异步请求获取数据
beforeMounted()// 未执行渲染,更新,虚拟DOM完成,真实DOM未创建
mounted()// 初始化阶段结束,真实DOM已经创建,可以发送异步请求获取数据,也可以访问dom元素
beforeUpdate()//更新前,可用于获取更新前各种状态数据
updated()//更新后执行该钩子函数,所有的状态数据是最新的。
beforeDestroy() // 销毁前执行,可以用于一些定时器的清除。
destroyed()//组件已经销毁,事件监听器被移除,所有的子实例也会被销毁。