前言:为什么有生命周期钩子函数?
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会
。
一、生命周期图示
二、解析生命周期钩子函数的执行时的相关数据和dom挂载情况
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js"></script>
</head>
<body>
<div id="app">
<p ref="p">{{ message }}</p>
</div>
<script type="text/javascript">
// el提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标,在实例挂载之后,元素可以用 vm.$el 访问。
// data是 Vue 实例的数据对象,实例创建之后,可以通过 vm.$data 访问原始数据对象。
var app = new Vue({
el: '#app',
data: {
message : "winne"
},
beforeCreate: function () {
console.group('beforeCreate 创建前状态===============》');
console.log("%c%s", "color:red" , "el : " + this.$el); //undefined
console.log("%c%s", "color:red","data : " + this.$data); //undefined
console.log("%c%s", "color:red","message: " + this.message) // undefined
},
created: function () {
console.group('created 创建完毕状态===============》');
console.log("%c%s", "color:red","el : " + this.$el); //undefined
console.log("this.$data :");
console.log( this.$data); //已被初始化
// console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message); //winne (已被初始化)
},
beforeMount: function () {
console.group('beforeMount 挂载前状态===============》');
console.log("%c%s", "color:red","el : " + (this.$el)); //已被初始化,形成了dom结构
console.log("this.$el :");
console.log(this.$el); // 还没有挂载,数据还没有渲染
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
mounted: function () {
console.group('mounted 挂载结束状态===============》');
console.log("%c%s", "color:red","el : " + this.$el); //已被初始化
console.log("this.$el :");
console.log(this.$el); // 已挂载,数据已渲染
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
beforeUpdate: function () {
console.group('beforeUpdate 更新前状态===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log("this.$el :");
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
updated: function () {
console.group('updated 更新完成状态===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log("this.$el :");
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
beforeDestroy: function () {
console.group('beforeDestroy 销毁前状态===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log("this.$el :");
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
destroyed: function () {
console.group('destroyed 销毁完成状态===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log("this.$el :");
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message)
}
})
</script>
</body>
</html>
解析:
1、beforeCreate
在实例初始化(new Vue()
)之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。
tip:
此时还无法访问methods,data,computed上的方法或数据。el 和 data 并未初始化
一般可以在这加个loading事件
2、created
实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
tip:
这是一个常用的生命周期,因为你可以调用methods中的方法、改变data中的数据,并且修改可以通过vue的响应式绑定体现在页面上、获取computed中的计算属性等等。
一般在这结束loading,还做一些数据计算初始化,实现函数自执行
3、beforeMonut
在挂载开始之前被调用:相关的 render 函数首次被调用。
tip:
在挂载前状态,el还是 {{message}},这里就是应用的 Virtual DOM(虚拟Dom)技术,先把坑占住了。到后面mounted挂载的时候再把值渲染进去。
4、mounted
el 被新创建的 vm.$ el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
注意 mounted
不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted
内部使用 vm.$nextTick
tip:
1.在这个周期内,对data的改变可以生效。但是要进下一轮的dom更新,dom上的数据才会更新。 2.这个周期可以获取 dom。
一般在这发起后端请求,拿回数据,配合路由钩子做一些事情
数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
5、beforeUpdate
数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
6、updated
data里的值被修改后,将会触发update的操作。
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。如果要相应状态改变,通常最好使用计算属性
或watcher
取而代之。
注意 updated
不会保证所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以在 updated
里使用 vm.$nextTick
7、beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。
tip:
这一步还可以用this来获取实例。
一般在这一步做一些重置的操作。比如清除掉组件中的 定时器 和 监听的dom事件
8、destroyed
调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,vue实例也会被销毁(包括子组件实例)。
9、activated
当我们在使用路由的keep-alive组件时,keep-alive 组件激活时调用。就是切换到了当前keep-alive组件时调用。
使用keep-alive标签时才会被激活。页面加载时执行,可以用于数据渲染。由于使用了keep-alive后,ajax的请求数据会被浏览器缓存,当需要数据重新渲染时(如去哪儿网城市不同,景点数据不同)也不会重新请求数据。这时,需要在activated中在发起ajax数据请求即可。
tip:
当我们在App.vue中使用了keep-alive组件时,如果发现进入到当前组件页面路由参数发生了变化,但是数据并没有更新,那么就要考虑是不是keep-alive组件防止重复渲染dom的问题。我们把请求当前渲染页面的数据放在这个钩子函数执行就可以解决了。
10、deactivated
keep-alive 组件停用时调用。就是当前改keep-alive组件已经被切换出去时调用。
——————————————————————————————————
参考原文如下:
https://blog.csdn.net/qq_43021088/article/details/84256467
https://blog.csdn.net/qq_27953863/article/details/80368701