1.下面是我对生命周期的一些理解 首先我们先看一下Vue生命周期图。
2.它可以分为八个阶段
钩子函数 | 函数描述 |
---|---|
beforeCreate | 组件实例刚被创建,组件属性计算之前,如data属性等。 |
created | 组件实例创建完成,属性已绑定,但DOM还未生成,$el属性还不存在。 |
beforeMount | 模板编译 | 挂载之前。 |
mounted | 模板编译 | 挂载之后。 |
beforeUpdate | 组件更新之前。 |
updated | 组件更新之后。 |
beforeDestroy | 组件销毁前调用。 |
destroyed | 组件销毁后调用。 |
3.结合代码让我们更好的去理解钩子函数
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="js/vue.min.js" ></script>
</head>
<body>
<div id="app">
<p>{{message}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
//beforeCreate执行时:data和el均未初始化,值为undefined
beforeCreate: function() {
console.group('------beforeCreate创建前状态-------------');
console.log(this.$el);
console.log(this.$data);
console.log(this.message)
},
//.created执行时:Vue 实例观察的数据对象data已经配置好,
//已经可以得到app.message的值,但Vue 实例使用的根 DOM 元素el还未初始化
created: function() {
console.group('------created创建完毕状态-------------');
console.log(this.$el);
console.log(this.$data);
console.log(this.message);
},
//beforeMount执行时:data和el均已经初始化,但从{{message}}等现象可以看出
//此时el并没有渲染进数据,el的值为“虚拟”的元素节点
beforeMount: function() {
console.group('------beforeMount挂载前状态-------------');
console.log(this.$el);
console.log(this.$data);
console.log(this.message);
},
//mounted执行时:此时el已经渲染完成并挂载到实例上
mounted: function() {
console.group('------mounted 挂载结束状态-------------');
console.log(this.$el);
console.log(this.$data);
console.log(this.message);
},
//修改vue实例的data时,vue就会自动帮我们更新渲染视图,
//在这个过程中,vue提供了beforeUpdate的钩子给我们,
//在检测到我们要修改数据的时候,更新渲染视图之前就会触发钩子beforeUpdate。
beforeUpdate: function () {
console.group('beforeUpdate 更新前状态-------------');
console.log(this.$el);
console.log(this.$data);
console.log(this.message);
//测试DOM
console.log('Dom结构是:' + document.getElementById('app').innerHTML);
},
//由于数据更改导致虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。
//当这个钩子被调用时,组件DOM已经更新,所以你现在可以执行依赖于DOM的操作。
//然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。
updated: function () {
console.group('updated 更新完成状态-------------');
console.log(this.$el);
console.log(this.$data);
console.log(this.message);
//测试DOM
console.log('Dom结构是:' + document.getElementById('app').innerHTML);
},
//实例销毁之前调用。在这一步,实例仍然完全可用
beforeDestroy: function () {
console.group('beforeDestroy 销毁前状态-------------');
console.log(this.$el);
console.log(this.$data);
console.log(this.message);
},
//Vue实例销毁后调用。调用后,Vue实例指示的所有东西都会解绑定,
//所有的事件监听器会被移除,所有的子实例也会被销毁。
destroyed: function () {
console.group('destroyed 销毁完成状态-------------');
console.log(this.$el);
console.log(this.$data);
console.log(this.message)
}
})
</script>
</html>
让我们一步一步详细解说八大钩子的作用。
(1)beforeCreate【创建前】:
beforeCreate: 这个时候我们发现data和el均未初始化,值为undefined。
(2)created【创建后】:
created: 完成了 data 数据的初始化,但挂载阶段尚未开始,所以$el 属性不可见。
(3)beforeMount【载入前】
beforeMount:在挂载开始之前被调用,相关的render函数首次被调用,在这个时候还不能访问DOM节点,此时我们的$el为虚拟的dom节点,在节点中的数据依然是{{data}}的形式,data里面的数据和模板生成html。此时还没有挂载html到页面上。
(4)mounted【载入后】:
mounted:此时el被新创建的vm.$el替换,并挂载到实例上去之后调用该函数,在这个时候可以访问DOM节点了,节点中的数据渲染完成,也就是说已经挂载到html页面了。
(5)beforeUpdate【更新前】和updated【更新后】:
让我们来看下更新前和更新后的区别如上图:
我们可以很清楚的发现当我们去改变message的值的时候,触发了beforeUpdate函数,这个时候$el的值已经更改了,但是dom并没有变动。到update的时候,才真正去更新dom结构。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
(6)beforeDestroy【销毁前】和destroyed【销毁后】:
可以发现beforeDestory和destoryed打印出来的结果并没有什么特别,el的值data的数据依然在的。这是因为$destroy只是销毁一个实例,清理它与其它实例的连接,解绑它的全部指令及事件监听器,并不会清除data的数据或者清除dom。
具体可参考: https://cn.vuejs.org/v2/api/#vm-destroy这就是vue生命周期,希望大家多多支持我
作者:三木