前言
前段时间面试的时候被问到了生命周期一些问题,因为博主用生命周期只用大部分只用到了很简单的created mounted destroyed
其他的用的非常少,导致答的不是太好,虽然网上一些教程已经说的非常清楚,部分还特别好,但是我还是想写一些自己的理解,能帮助大家最好,也能帮助自己复习。
vue生命周期图示
官网上这张图相信大家都不陌生,官网是这么描述的:
下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。
这张图直接了当的展示了八个钩子函数依次分别是
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- bedoreDestroy
- destroyed
再贴一段代码(这段代码可以复制直接使用) 参考链接
<!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 id="text">{{ message }}</p>
<button v-on:click="fun">改变</button>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message : "xuxiao is boy"
},
methods:{
fun(){
this.message = 'hello world'
}
},
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)
},
created: function () {
console.group('created 创建完毕状态===============》');
console.log("%c%s", "color:red","el : " + this.$el); //undefined
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
beforeMount: function () {
console.group('beforeMount 挂载前状态===============》');
console.log("%c%s", "color:red","el : " + (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("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
beforeUpdate: function () {
console.group('beforeUpdate 更新前状态===============》');
console.log(document.getElementById("text").innerHTML,"````````````beforeUpdate`````````````````")
console.log("%c%s", "color:red","el : " + 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(document.getElementById("text").innerHTML,"`````````````updated```````````````")
console.log("%c%s", "color:red","el : " + 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("%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("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message)
}
})
</script>
</body>
</html>
下面依次讲解各个钩子函数的用处:
beforeCreate
- 类型:
Function
- 详细:
在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
在这个钩子函数中,数据还没有监听,没有绑定到vue对象实例,同时也没有挂载对象,更加取不到data
中的数据
- 延伸扩展:
- 问:vue怎么在
beforeCreate
里获取data
。(项目中基本不会遇见这类需求,但是有些面试喜欢问) - 答:
setTimeout或者this.$nextTick
。
- 问:vue怎么在
var vm = new Vue({
el: '#app',
data() {
return {
message: "hello world"
}
},
beforeCreate() {
// 相当于在初始化前告诉容器,等全执行完了再跑里面的代码。
this.$nextTick(function () {
console.log(this.message); // hello world
})
}
});
created
- 类型:
Function
- 详细:
在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
组件实例创建完成,属性已经绑定,但是DOM
还未生成,$el
还不存在,这一步已经可以获取data中的数据了,但是还获取不到DOM元素,还未进行挂载。
一般可以在created函数中调用ajax获取页面初始化所需的数据。
beforeMount
- 类型:
Function
- 详细:
在挂载开始之前被调用:相关的render
函数首次被调用。
该钩子在服务器端渲染期间不被调用。
完成了 el 和 data 初始化,但是还没有进行挂载~
tips:
很多新手可能不太懂挂载什么意思(博主当初就不怎么懂),博主没有找到官方的定义,但是博主在一篇react
教程里,看到这句定义,给大家分享参考下:
我们把 React.js 将组件渲染,并且构造 DOM 元素然后塞入页面的过程称为组件的挂载(这个定义请好好记住)。
再用代码解释下:
<div id="app">
<p id="text">{{ message }}</p>
</div>
...
data:{
message : "hello world"
},
beforeMount(){
console.log(document.getElementById("text")) // <p id="text">{{ message }}</p>
},
mounted(){
console.log(document.getElementById("text")) // <p id="text">hello world</p>
},
...
mounted
- 类型:
Function
- 详细:
el
被新创建的vm.$el
替换,并挂载到实例上去之后调用该钩子。如果root 实例
挂载了一个文档内元素,当mounted
被调用时vm.$el
也在文档内。
完成了 el 和 data 初始化,完成挂载~
注意 mounted
不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick
替换掉 mounted
:
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}
该钩子在服务器端渲染期间不被调用。
beforeUpdate
- 类型:
Function
- 详细:
数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。
update
- 类型:
Function
- 详细:
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性
或 watcher
取而代之。
注意 updated
不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick
替换掉 updated
:
updated: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been re-rendered
})
}
该钩子在服务器端渲染期间不被调用。
beforeDestory
- 类型:
Function
- 详细:
实例销毁前调用,在这一步,实例仍然完全可用。
可以在这个钩子函数中,清除页面定义的定时器。
该钩子在服务器端渲染期间不被调用。
destroyed
- 类型:
Function
- 详细:
Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
该钩子在服务器端渲染期间不被调用。
用vm.$destroy()
,用v-if也会触发子组件销毁,销毁一个组件的时候会触发beforeDestroy和destroyed
总结
第一次写博客,写的不好的地方多多见谅,希望能和大家共同进步。