生命周期和监听函数(钩子函数)
基本说明
- Vue 实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂载DOM、渲染-更新-渲染、卸载等一系列过程,我们称为 Vue 实例的生命周期。
- 钩子函数(监听函数): Vue 实例在完整的生命周期过程中(比如设置数据监听、编译模板、将实例挂载到 DOM 、在数据变化时更新 DOM 等), 也会运行叫做生命周期钩子的函数。
- 钩子函数的 作用就是在某个阶段, 给程序员一个做某些处理的机会。
图解

new Vue()
new 了一个 Vue 的实例对象,此时就会进入组件的创建过程。
Init Events & Lifecycle
初始化组件的事件和生命周期函数。
beforeCreate
组件创建之后遇到的第一个生命周期函数,这个阶段 data 和 methods 以及 dom 结构都未被初始化,也就是获取不到 data 的值,不能调用 methods 中的函数。
Init injections & reactivity
这个阶段中, 正在初始化 data 和 methods 中的方法。
created
这个阶段组件的 data 和 methods 中的方法已初始化结束,可以访问,但是 dom 结构未初始化,页面未渲染(在这个阶段,经常会发起Ajax请求)
编译模板结构(在内存)
beforeMount
当模板在内存中编译完成,此时内存中的模板结构还未渲染至页面上,看不到真实的数据。
Create vm.$el and replace 'el' with it
这一步,再在把内存中渲染好的模板结构替换至真实的 dom 结构也就是页面上。
mounted
此时,页面渲染好,用户看到的是真实的页面数据, 生命周期创建阶段完毕,进入到了运行中的阶段。
生命周期运行中
beforeUpdate
当执行此函数,数据池的数据新的,但是页面是旧的。
Virtual DOM re-render and patch
根据最新的 data 数据,重新渲染内存中的模板结构,并把渲染好的模板结构,替换至页面上。
updated
页面已经完成了更新,此时,data 数据和页面的数据都是新的。
beforeDestroy
当执行此函数时,组件即将被销毁,但是还没有真正开始销毁,此时组件的 data、methods 数据或方法还可被调用。
Teardown
注销组件和事件监听
destroyed
组件已经完成了销毁
应用实例
需求
展示 VUE 实例生命周期和 钩子函数/监听函数/生命周期函数 执行时机 (1)重 点 研 究 几 个 重 要 的 钩 子 函 数 (beforeCreate, created, beforeMount, mounted, beforeUpdate, updated) (2)在这几个钩子函数中, 数据模型是否加载/使用? 自定义方法是否加载/可用? html 模板是否加载/使用? html 模板是否完成渲染?
代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue生命周期和钩子函数</title>
<script src="vue.js"></script>
</head>
<body>
<!--这里可以视为用户看到的页面-对应前面讲解的页面dom-->
<div id="app">
<span id="num">num={{num}}</span>
<button @click="num++">点赞!</button>
<h2>{{name}},有{{num}}次点赞</h2>
</div>
<script>
let vm = new Vue({
el:"#app",
data:{//数据池
name:"kristina",
num:0
},
methods:{
show(){
return this.name;
},
add(){
this.num++;
}
},
beforeCreate(){
//生命周期函数-创建vue实例前
console.log("=============beforeCreate==========");
console.log("数据模型/数据池的数据是否加载/使用?[no]", this.name, " ", this.num);
// console.log("自定义方法是否加载/使用?[no]", this.show());
console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);
},
created() {
//生命周期函数-创建vue实例
console.log("=============created==========");
console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
console.log("自定义方法是否加载/使用?[yes]", this.show());
console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);
//可以发出Ajax
//接收返回的数据
//再次去更新data数据池的数据
//编译内存模板结构
//.....
},
beforeMount(){
//生命周期函数-挂载前
console.log("=============beforeMount==========");
console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
console.log("自定义方法是否加载/使用?[yes]", this.show());
console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);
},
mounted() {
//生命周期函数-挂载后
console.log("=============mounted==========");
console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
console.log("自定义方法是否加载/使用?[yes]", this.show());
console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
console.log("用户页面dom是否被渲染?[yes]", document.getElementById("num").innerText);
},
beforeUpdate() {
//生命周期函数-数据池数据更新前
console.log("=============beforeUpdate==========");
console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
console.log("自定义方法是否加载/使用?[yes]", this.show());
console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
console.log("用户页面dom数据是否被更新?[no]", document.getElementById("num").innerText);
// 验证数据==>修正
// if(this.num < 10 ) {
// this.num = 8;
// }
},
updated() {
//生命周期函数-数据池数据更新后
console.log("=============updated==========");
console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
console.log("自定义方法是否加载/使用?[yes]", this.show());
console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
console.log("用户页面dom数据是否被更新?[yes]", document.getElementById("num").innerText);
}
})
</script>
</body>
</html>
Vue 实例生命周期是非常重要,Vue 编程模型都是建立在此基础上