Vue 的生命周期是指 Vue 实例从创建、挂载、更新、销毁的整个过程。Vue 提供了一系列的生命周期钩子函数,允许开发者在特定阶段执行自定义的代码。
生命周期执行顺序
执行顺序为beforeCreate,created,beforeMount,mounted。当组件内容发生变化的时候会执行beforeUpdate,updated。当组件销毁的时候会执行beforeDestroy,destroyed
这里来演示下。
<template>
<div id="box">
<div @click="numAdd"> num:{{ num }}</div>
<button @click="hidePage">销毁组件</button>
</div>
</template>
<script>
export default {
data(){
return {
num:null,
}
},
beforeCreate(){
console.log('beforeCreate');
},
created(){
console.log('created');
},
beforeMount(){
console.log('beforeMount');
},
mounted(){
console.log('mounted');
},
beforeUpdate(){
console.log('beforeUpdate');
},
updated(){
console.log('updated');
},
beforeDestroy(){
console.log('beforeDestroy');
},
destroyed(){
console.log('destroyed');
},
methods:{
numAdd(){
this.num++
},
hidePage(){
// 手动销毁实例
this.$destroy();
}
}
}
</script>
<style>
#box{
width: 300px;
height: 200px;
border: 1px solid;
margin: 200px auto;
}
</style>
当页面加载完成后会调用这几个生命周期
当点击num,num++组件发生了变化。beforeMount和mounted执行
点击销毁组件,beforeDestroy和destroyed执行。另外当组件销毁后在点击num就不会在触发num++了。
应用
beforeCreate
在beforeCreate钩子函数中,this已经实例化成功了,但是data和methods还没有初始化。在当前钩子函数中是访问不到的。当前钩子函数中可以初始化一些全局的插件或者库。
<template>
<div>
</div>
</template>
<script>
export default {
data(){
return{
name:'张三'
}
},
beforeCreate(){
console.log('name',this.name);
this.getName();
},
methods:{
getName(){
console.log('name',this.name);
}
}
}
</script>
<style>
</style>
打印结果可以到,name为undefined。调用getName方法则报错提示未找到方法。
created
实例已经创建完成之后被调用created。可以访问到data和methods了,但是dom元素还没有加载完成。在该钩子函数中获取dom元素则会undefined。这里尝试通过ref在created钩子函数中获取h2标签。对ref获取dom元素不了解的可以看下这里 vue2中ref的使用
<template>
<div>
<h2 ref="myh2">在created获取dom元素</h2>
</div>
</template>
<script>
export default {
data(){
return{
name:'张三'
}
},
created(){
console.log('created',this.name);
this.getName();
console.log('myh2',this.$refs.myh2);
},
methods:{
getName(){
console.log('name',this.name);
}
}
}
</script>
<style>
</style>
运行结果
beforeMount
在该钩子函数中,相关的render函数首次被调用,模板已经编译好了,还没有挂载到页面上。该钩子函数使用较少,因为dom还没实际渲染,对dom的操作没有实际效果。
mounted
在该钩子中,dom元素挂载完成。可以获取dom进行操作。在使用eachts.js或其他依赖dom的第三方库的操作都在该钩子函数中进行。在该阶段在去获取 h2标签即可成功
mounted(){
console.log('myh2',this.$refs.myh2);
},
beforeUpdate
此时数据已经发生变化,但 DOM 还未更新。在这里进行一些数据的预处理,或者记录更新前的状态。这里使用oldAA来存储旧值。
<template>
<div>
<div @click="changeAA">aa:{{ aa }}</div>
</div>
</template>
<script>
export default {
data(){
return{
aa:'111',
oldAA:null,
}
},
beforeUpdate(){
console.log('修改之前的值为',this.oldAA);
console.log('aa',this.aa);
},
methods:{
changeAA(){
this.oldAA=this.aa;
this.aa='222'
}
}
}
</script>
运行结果
updated
dom元素修改完成,可以获取更新完成后的dom信息。比如根据更新后的数据重新计算元素的位置或大小等操作。这里在aa更新完成后修改下元素的样式。
<template>
<div>
<div ref="myaa" @click="changeAA">aa:{{ aa }}</div>
</div>
</template>
<script>
export default {
data(){
return{
aa:'111',
oldAA:null,
}
},
beforeUpdate(){
console.log('修改之前的值为',this.oldAA);
console.log('aa',this.aa);
},
updated(){
this.$refs.myaa.style.color='red'
},
methods:{
changeAA(){
this.oldAA=this.aa;
this.aa='222'
}
}
}
</script>
beforeDestroy
在实例销毁之前调用。此时实例仍然完全可用。在这里可以进行移除之前注册的全局事件监听器,定时器等操作。
destroyed
在实例销毁之后调用。此时所有的事件监听器和子实例都已经被销毁。比如上面生命周期执行顺序demo中演示的。当手动销毁实例后,在点击num,num已经不会在num++了。
end
理解和掌握生命周期钩子函数,可以更好地控制 Vue 实例的行为。(如有误欢迎指正)