Vue生命周期是Vue核心的概念,是Vue执行的全过程 每个 Vue
实例在被创建时都要经过一系列的初始化过程,数据监听,模板编译,挂载实例到DOM,更新DOM,销毁DOM,这个过程就是Vue生命周期钩子,下面我就将我学到的Vue生命周期来做一个梳理
1.生命周期图解
下面是Vue官网赋予的一张生命周期全程图片,可以分为4对(创建,挂载,更新,销毁),8个钩子(执行前和执行后),像慢动作播放
beforeCreate(创建前)
created(已创建)
beforeMount(挂载前)
mounted(已挂载)
beforeUpdate(更新前)
updated(已更新)
beforeDestroy(销毁前)
destroyed(已销毁)
2.生命周期详解
2.1 new Vue()
<div id="root">
<h2>当前的n值是:{
{n}}</h2>
<button @click="add">点击加1</button>
<button @click="bye">删除</button>
</div>
<script>
Vue.config.productionTip = false;
//请编写代码
new Vue({
el: "#root",
data: {
n: 1,
},
methods: {
add() {
this.n++;
},
bye() {
this.$destroy()
}
},
</script>
实例化Vue对象;没有这一步,就没有后面的钩子了
2.2 init Events $Lifecycle
初始化:在这个阶段进行初始化;生命周期,事件,数据代理等均未开始
2.3 beforeCreate(创建前)
在js里面写一段代码
beforeCreate() {
console.log('beforeCreate');
console.log(this);
console.log(this.$el);
debugger;
},
页面渲染结果如下
通过观察不难发现vue里面没有模板内容;无法通过vm访问到data中的数据,methods中的方法 此时this指向vm
2.4 init injections $ reactivity
初始化:数据监测 数据代理 属性赋值 computed的运算
2.5 created(已创建)
create() {
console.log('create');
console.log(this);
debugger;
},
结果如下
可以通过vm访问到data中的数据,methods配置项中的方法;但是,这会还没有挂在dom。页面没有实际DOM;不能访问到 e l , el, el,ref属性内容未空数组
2.6 判断阶段
判断是否有“el”选项 和 “template”选项
判断对象上是否有el选项,如果有的话,就继续向下编译,如果没有,就停止编译,说明停止了生命周期
如果对象有el选项之后,判断是否有template项,如果有则将其作为编译模板编译成render函数。如果没有template模板,则将外部的HTML作为模板编译
现在Vue开始解析模板,生成虚拟DOM(内存中) 页面还不能显示解析好的内容
2.7 beforeMount(挂载前)
beforeMount() {
console.log('beforeMount');
console.log(this);
debugger;
},
vue 实例的 $el 和 data 都已初始化,挂载之前为虚拟的 dom节点,模板已经在内存中编辑完成了,但是尚未把模板渲染到页面中
2.8 Create vm.$el and replace “el” with it
将内存中的额虚拟DOM转为真实的DOM 并插入页面
2.9 mounted(已挂载)
mounted() {
console.log('mounted');
console.log(this);
console.log(this.$el);
debugger;
},
至此,页面呈现经过编译的DOM 对DOM操作奏效 $ref属性可以访问 初始化过程结束 可以开启定时器等等
vue 实例挂载完成,data.message 成功渲染。内存中的模板,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了
2.10 beforeUpdate(更新前)
beforeUpdate() {
console.log('beforeUpdate');
console.log(this.n);
debugger;
},
数据和页面尚未保持同步 数据是新的,页面是旧的 vue(组件)对象对应的dom中的内部(innerHTML)没有变,所以叫作组件更新前
2.11 updated(已更新)
updated() {
console.log('updated');
console.log(this.n);
debugger;
},
数据和页面保持同步
2.12 beforeDestroy(销毁前)
beforeDestroy() {
console.log('beforeDestroy');
debugger;
},
vm中所有data,methods,指令等还可以使用,这一步,实例仍然完全可用,this仍能获取到实例,准备关闭定时器,取消订阅消息等等
2.13 destroyed(已销毁)
destroyed() {
console.log('destroyed');
debugger;
}
销毁完毕
所有代码
Vue.config.productionTip = false;
//请编写代码
new Vue({
el: "#root",
data: {
n: 1,
},
methods: {
add() {
this.n++;
},
bye() {
this.$destroy()
}
},
//初始化 生命周期 事件 但数据代理未开始 无法通过vm访问到data中的数据 methods中的方法
beforeCreate() {
console.log('beforeCreate');
console.log(this);
},
// 页面可以获取到data和methods里面的数据
create() {
console.log('create');
console.log(this);
},
//el template 阶段 判断是否有el 和 template(模板) 属性项
// 可以把模板写在属性项template里面 使用es6里的反引号 但是不能使用template作为根标签
// 页面开始解析模板 生成虚拟DOM(在内存中) 页面还不能显示解析好的内容
// beforeMount 页面显示未经vue编译的DOM结构 所有对DOM的操作 最终不奏效
beforeMount() {
console.log('beforeMount');
console.log(this);
},
// 页面中呈现的是经过vue编译的DOM 对DOM的操作均有效(尽可能避免)到这里初始化过程结束 开启定时器 发送网络请求 订阅消息 绑定自定义事件等初始化操作
mounted() {
console.log('mounted');
console.log(this);
console.log(this.$el);
},
beforeUpdate() {
console.log('beforeUpdate');
console.log(this.n);
},
updated() {
console.log('updated');
console.log(this.n);
},
// // 还可以访问到数据 调用到方法 但是不能再修改数据
beforeDestroy() {
console.log('beforeDestroy');
},
destroyed() {
console.log('destroyed');
debugger;
}
})
总结:
1、beforeCreate(创建前) 表示实例完全被创建出来之前,vue 实例的挂载元素el和数据对象 data 都为 undefined,还未初始化,this指向创建的实例,不能访问到data,computed,watch,methods上的方法和数据,此时,vue组件对象被创建,但是vue对象的属性还没有绑定,即没有值。
2、created(创建后) 数据对象data已存在,可以调用methods中的方法,操作data中的数据,但dom未生成,el未存在数据对象 data 已存在,可以调用 methods 中的方法,操作 data 中的数据,但 dom 未生成,$el 未存在
3、beforeMount(挂载前) vue 实例的 $el 和 data 都已初始化,挂载之前为虚拟的 dom节点,模板已经在内存中编辑完成了,但是尚未把模板渲染到页面中。data.message 未替换。
4、mounted(挂载后) vue实例挂载完成,data.message 成功渲染。内存中的模板,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了。实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,DOM 渲染在 mounted 中就已经完成了。
5、beforeUpdate(更新前) 当data 变化时,会触发beforeUpdate方法 。data 数据尚未和最新的数据保持同步
6、updated(更新后) 当 data 变化时,会触发 updated 方法。页面和 data 数据已经保持同步了。
7、beforeDestory(销毁前) 组件销毁之前调用,在这一步,实例仍然完全可用。
8、destoryed(销毁后)组件销毁之后调用,对 data 的改变不会再触发周期函数,vue 实例已解除事件监听和 dom绑定,但 dom 结构依然存在。