生命周期
生命周期函数是Vue在关键时刻帮我们调用的一些特殊名称的函数。
别名:生命自周期函数、生命周期回调函数、生命周期钩子
生命周期函数的名字不可以更改,但函数的具体内容是开发人员根据需求自己编写的。
生命周期函数中的this
指向的是vm或者组件实例对象。
示例:
new Vue({
el: '#app',
data: {
opacity: 1
},
// Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted生命周期函数
mounted() {
// this指向的是vm
console.log('mounted', this);
setInterval(() => {
this.opacity -= 0.01 ;
if(this.opacity <= 0) vm.opacity = 1;
}, 16);
},
});
Vue生命周期图示:
挂载流程
Init(Events & Lifecycle)
:初始化生命周期、事件,但数据代理还未开始- 调用
beforeCreate
:此时无法通过vm访问到data中的数据、methods中的方法 Init(Injections & reactivity)
:初始化数据监测、数据代理- 调用
created
:此时可以通过vm访问到data中的数据、methods中配置的方法 - 判断并编译
el
、template
:此阶段Vue开始解析模板,生成虚拟DOM(内存中),页面还不能显示解析好的内容 - 调用
beforeMount
:此时页面呈现的是未经Vue编译的DOM结构。此时所有对DOM的操作,最终都会被替换掉,不会奏效 Create vm.$el and replace 'el' with it
:将内存中的虚拟DOM转换为真实DOM插入页面- 调用
mounted
:此时页面呈现的是经过Vue编译的DOM。此处对DOM的操作会生效(但是尽可能避免直接操作DOM)。至此,初始化过程结束。一般在此处进行:开启定时器、发送网络请求、订阅消息、绑定自定义事件等初始化操作
使用vm.$mount替代el
当Vue配置项中没有el
配置时,Vue解析走到created
步骤(初始化数据监测、数据代理)就停止了。当vm.$mount(el)
调用时才继续向下运行。
const vm = new Vue({
data: {
opacity: 1
},
beforeCreate() {
console.log('beforeCreate');
},
created() {
console.log('created');
},
beforeMount() {
console.log('beforeMount');
},
mounted() {
console.log('mounted');
}
};
// 走到create步骤即会停止
// 调用vm.$mount(el)时会继续向下运行
vm.$mount('#app');
template配置项
可以将模板写到Vue的template
配置项中:
<body>
<div id="app"></div>
</body>
<script>
Vue.config.productionTip = false;
new Vue({
el: '#app',
template: `
<div id='newDiv'>
<h2>{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>`,
data: {
n:1
}
});
</script>
注意事项:Vue2中, template
配置的模板中,有且只有一个根标签,例如上面示例中的<div id='newDiv'>
。而且这个根标签需要是真实的DOM标签,不能使用Vue的虚拟标签<template>
作为根标签。
vue 3 中新增了一个标签来解决这个问题。
Vue会使用template
的内容替换掉el
配置的根标签,即最终页面上不会出现<div id='app'>
,而会出现<div id='newDiv'>
更新流程
- 在
Mounted
阶段,当data发生改变时 - 调用
beforeUpdate
:此时数据是新的,但页面时旧的,即:页面尚未和数据保持同步 Virtual Dom re-render and patch
:根据新数据,生成新的虚拟DOM,随后与旧的虚拟DOM进行比较,最终完成页面更新,即:完成了Model
->View
的更新- 调用
updated
:此时数据是新的,页面也是新的,即:页面和数据保持同步
销毁流程
- 当用户调用了
vm.$detroy()
时,开始进入销毁流程 - 调用
beforeDestroy()
:此时VM中所有的data、methods、指令都处于可用状态,马上要执行销毁过程。一般在此阶段:关闭定时器、取消订阅消息、解绑自定义事件等等收尾操作。 Teardown wathcers, child, components and event listeners
- 调用
destroyed()
:很少使用该钩子
总结
常用的生命周期钩子:mounted
、beforeDestroy
另外还有一些其他和路由相关的生命周期钩子。
销毁Vue实例:
- 销毁后借助Vue开发者工具看不到任何信息
- 销毁后自定义事件会失效,但是之前通过
v-bind
绑定的原生DOM事件(on-click
等)依然有效 - 一般不会在
beforeDestroy
中操作护具,因为即使操作数据,也不会再触发更新流程了。