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()
}
},
beforeCreate() {
console.log('beforeCreate');
console.log(this);
},
create() {
console.log('create');
console.log(this);
},
beforeMount() {
console.log('beforeMount');
console.log(this);
},
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 结构依然存在。
|