Vue生命周期
# 1 单组件的生命周期
# 1) 什么是生命周期
一个Vue实例从创建到销毁的整个过程. Vue组件也可看成一个Vue实例
# 2) 生命周期函数(钩子)
在生命周期中, 特定的时间点会被自动执行的函数
- beforeCreate()
- created()
- beforeMount()
- mounted()
- beforeUpdate()
- updated()
- beforeDestroy()
- destroyed()
# 3) Vue实例到底做了一件什么事
Vue实例的最主要的工作是
将模板内容编译, 替换掉原有的html节点
- 模板内容: 由
template
选项确定 - 编译: 由
render()
方法, 将模板编译成在真实的DOM, 渲染在html文件中 - 原有的html节点: 由
el
选项确定
示例
<div id="app"></div>
<script>
const vm = new Vue({
el: '#app',
template: '<div>hello</div>',
})
</script>
2
3
4
5
6
7
8
vue实例最终就是将<div>hello</div>
替换掉了原有的html中<div id="app"></div>
节点
示例
const vm = new Vue({
el: '#app',
data: {
msg: 'hello',
},
template: '<div>{{msg}}</div>',
})
2
3
4
5
6
7
这里, 会难一点点, 流程是:
- 先解析
template
中的内容, 将替换成
hello
(这个过程叫作编译) - 将编译的结果
<div>hello</div>
替换掉了原有的html中<div id="app"></div>
节点
在这个过程中, 会有一些时间点, 在这些时间点会自动调用一些函数. 这些就是生命周期函数
示例
const vm = new Vue({
el: '#app',
data: {
msg: 'hello',
},
template: '<div>{{msg}}</div>',
beforeCreate() {
console.log(this, 'beforeCreate')
},
created() {
console.log(this, 'created')
},
beforeMount() {
console.log(this, 'beforeMount')
},
mounted() {
console.log(this, 'mounted')
},
beforeUpdate() {
console.log(this, 'beforUpdate')
},
updated() {
console.log(this, 'updated')
},
beforeDestroy() {
console.log(this, 'beforeDestroy')
},
destroyed() {
console.log(this, 'destroyed')
},
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
我们发现, 有4个函数被执行了
- beforeCreate()
- created()
- beforeMount()
- mounted()
这四个函数在整个生命周期中只执行一次
# 4) 生命周期函数
# create相关函数
create相关的生命周期函数有两个:
- beforeCreate()
- created()
beforeCreate和created的相同点
都是在Vue实例创建时被调用, 只执行一次
beforeCreate和created的不同点
要搞清楚这个问题, 我们需要知道在beforeCreate和created之间, 做了什么事
示例
beforeCreate() {
console.dir(this.$data) // undefined
console.log(this, 'beforeCreate')
},
created() {
console.dir(this.$data) // object
// 跟数据相关, 放在created中
console.log(this, 'created')
}
2
3
4
5
6
7
8
9
我们发现, 在beforeCreate中$data
是undefined, 而created中$data
是有值的
因此, 我们得出一个重要结论
重要结论
如果要处理跟数据相关的逻辑, 最早在created函数中处理
一句话总结
在beforeCreate和created之间, 完成$data的代理
场景
- 如果发送ajax请求从后台拿数据, 建议放到created里
- 如果要完成data数据的初始化, 建议放到created里
# mount相关函数
mount相关的生命周期函数有两个:
- beforeMount()
- mounted()
create和mount的不同
created结束时还不能操作DOM, mounted结束时才可以操作DOM
示例
created() {
console.dir(this.$data)
// 跟数据相关, 放在created中
console.log(this.$el, 'created') // undefined
},
beforeMount() {
console.log(this.$el, 'beforeMount') // <div id="app"></div>
},
mounted() {
// 跟DOM操作相关, 放在mounted中
console.log(this.$el, 'mounted') // <div>hello</div>
},
2
3
4
5
6
7
8
9
10
11
12
created表示实例创建完成, 而mounted表示挂载完成, 是new Vue
时的两个步骤
怎么将这两个步骤分开呢
示例
const vm = new Vue({
// 第一步: 注释掉el
// el: '#app',
data: {
msg: 'hello',
},
template: '<div>{{msg}}</div>',
beforeCreate() {
console.dir(this.$data)
console.log(this.$el, 'beforeCreate')
},
created() {
console.dir(this.$data)
// 跟数据相关, 放在created中
console.log(this.$el, 'created')
},
beforeMount() {
console.log(this.$el, 'beforeMount')
},
mounted() {
// 跟dom操作相关, 放在mounted中
console.log(this.$el, 'mounted')
},
beforeUpdate() {
console.log(this, 'beforUpdate')
},
updated() {
console.log(this, 'updated')
},
beforeDestroy() {
console.log(this, 'beforeDestroy')
},
destroyed() {
console.log(this, 'destroyed')
},
})
// 第二步: 调用$mount方法, 手动挂载
vm.$mount('#app')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
如果不指定el
选项: 不会执行mount相关的生命周期
手动调用$mount
方法挂载时, 发现mount相关的生命周期被调用了
mount是把什么挂载到什么上
mounted结束时, 将编译之后的模板挂载到了html上, 替换原有的节点.
通过上面的分析, 我们知道了:
Vue实例化过程中最主要两步是
- 编译
- 挂载
beforeMount和mounted的不同点
要搞清楚这个问题, 我们需要知道在beforeMount和mounted之间, 做了什么事
示例
beforeMount() {
console.log(this.$el, 'beforeMount') // <div id="app"></div>
},
render(h) {
console.log('render in invoked')
return h('div', {}, this.msg)
},
mounted() {
// 跟dom操作相关, 放在mounted中
console.log(this.$el, 'mounted') // <div>hello</div>
},
2
3
4
5
6
7
8
9
10
11
在beforeMount和mounted之间, 调用了render
方法, 将模板编译成了html
# update相关函数
update相关的生命周期函数有两个:
- beforeUpdate()
- updated()
beforeUpdate和updated的相同点
都是在Vue的data中的数据发生改变时调用, 可以执行N次(N>=1)
beforeUpdate和updated的不同点