每个Vue实例都会在创建时经历一系列的初始化过程——例如,需要设置数据监听,编译模板,将实例挂载到DOM上并在数据变化时更新DOM等。同时在这个过程中也会运行一些叫生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
从上图我们可以将Vue的生命周期分为三个节点:
- create——创建实例
- mounte——挂载DOM
- destroy——实例摧毁
Vue一共有八个生命周期钩子函数,这些函数会在特定时间被调用:
钩子函数 | 调用时间 |
---|---|
beforeCreate | 创建该Vue实例之前 |
created | 创建该Vue实例之后 |
beforeMount | 将实例挂载到DOM上之前 |
mounted | 将实例挂载到DOM之后 |
beforeUpdate | 实例已经被挂载到DOM上直到该实例被摧毁期间,更新模板渲染之前 |
updated | 实例已经被挂载到DOM上直到该实例被摧毁期间,更新模板渲染之后 |
beforeDestroy | 实例被摧毁之前 |
destroyed | 实例被摧毁之后 |
为了更好地理解Vue生命周期,我们创建一个cycle.vue
<template>
<div class="hello">
{{info}}
<div @click="changeInfo">点击这里</div>
</div>
</template>
<script>
export default {
name: 'cycle',
data(){
return {
info: 'hello, vue'
}
},
methods:{
changeInfo(){
this.info = this.info.toUpperCase()
}
},
beforeCreate() {
debugger;
console.log("Cycle before create");
console.log("info in data: " + this.info)
},
created() {
debugger;
console.log("Cycle created");
console.log("info in data: " + this.info)
},
beforeMount() {
debugger;
console.log("Cycle before mount");
console.log("info in data: " + this.info)
},
mounted() {
debugger;
console.log("Cycle mounted");
console.log("info in data: " + this.info)
},
beforeUpdate() {
debugger;
console.log("Cycle beforeUpdate");
console.log("info in data: " + this.info)
},
updated() {
debugger;
console.log("Cycle updated");
console.log("info in data: " + this.info)
}
}
</script>
<style scoped>
</style>
-
当渲染此组件时,首先进入了beforeCreate,
观察右边的变量,我们不难发现,这时候该Vue实例还没有初始化,data,props等实例数据都还是undefined
,并且控制台没有输出。 -
恢复脚本执行,进入Created
控制台:
浏览器:
这时候,data已经初始化完成,并且控制台打印了beforeCreate的相应信息,说明该Vue实例初始化完成,但是浏览器界面还是没有出现任何网页元素。 -
恢复脚本执行,进入beforeMount:
我们发现,这时候Vue实例出现了一个新的变量$el
,同样的,现在页面上依然和created一样,没有展示任何网页元素:
-
恢复脚本执行,进入mounted:
控制台:
浏览器页面:
此时,Vue实例的$el
已经更新,并且页面上展示了cycle组件,$el的值就是该Vue实例挂载的DOM对象,当该Vue实例挂载到DOM对象上之后,我们就能看到内容了。 -
如果在挂载之后,我们点击
点击这里
,这会执行相应的点击事件,将this.info设置为大写形式,这就会进入到beforeUpdata。值得注意的是,我们在beforeUpdata中对this.info进行输出,这里输出的值是新值(HELLO, VUE)还是旧值(hello, vue)呢?
有人可能会这么想,我们目前处于beforeUpdata钩子函数,现在并没有更新渲染,确实,我们可以看到浏览器页面是这样的:
上面依然是hello, vue,而不是HELLO, VUE,所以,有人会认为beforeUpdata中的输出语句会输出hello, vue。但是,其实当我们点击完执行了点击事件之后,this.info就已经变成了HELLO,VUE,只是还没有执行渲染,所以界面还没有发生改变。
所以,这里的输出是HELLO,VUE。 -
集训执行脚本,进入updated,这时候,页面已经被重新渲染了,所以显示的内容和实例的数据一致。
-
beforeDestroy和destroyed大家可以自行测试,和create节点前后的beforeCreate和created类似。