生命周期图解
生命周期的钩子函数(vue1.0 - vue2.0)
vue 1.0 + | vue 2.0 | Description |
---|---|---|
init | beforeCreate | 组件实例刚被创建,组件属性计算之前,如 data 属性等 |
created | created | 组件实例创建完成,属性已绑定,但DOM还未生成,$el 属性还不存在 |
beforeCompile | beforeMount | 模板编译 / 挂载之前 |
compiled | mounted | 模板编译 / 挂载之后 |
ready | mounted | 模板编译 / 挂载之后(不能保证组件已在 document 中) |
- | beforeUpdate | 组件更新之后 |
- | updated | 组件更新之后 |
- | activated | for keep-alive,组件被激活时调用 |
- | deactivated | for keep-alive,组件被移除时调用 |
attached | - | 将 vm.el 附加到 dom 时调用,直接操纵 vm.$el 不会触发这个钩子 |
datached | - | 从 dom 中移除 vm.$el 时调用,直接操纵 vm.$el 不会触发这个钩子 |
beforeDestroy | beforeDestroy | 组件销毁前调用 |
destroyed | destroyed | 组件销毁后调用 |
vue 的生命周期简单来说就是 vue 实例从创建到销毁的过程。 | ||
一个完整的生命周期,总共分为三个阶段:挂载阶段 (进入页面阶段)、更新阶段、销毁阶段(卸载阶段)。 |
1. beforeCreate
- 说明 : 在实例初始化之前,数据观测 和
event/watcher
事件配置之前被调用 - 组件实例刚被创建,组件属性计算之前, 例如
data
属性methods
属性 - 注意 : 此时,无法获取
data
中的数据 和methods
中的方法 - 场景 : 几乎不用
2. created
- 说明 : 组件实例创建完成,属性已绑定, 可以调用
methods
中的方法、可以获取data
值 - 注意 : 在这里更改数据不会触发
updated
函数 - 场景 : 一般可以在这里做初始数据的获取
Has ‘el’ option ?
- YES => 就是正常的
el
边界 - NO => 可以注释,但是必须要手动添加
vm.$mount(el)
去指定边界
Has template option?
- No => 将
el
的outerHtml
作为模板进行编译 (outerHTML
= 自身 +innerHTML
) - YES =>
vue
就会将template
的内容进行编译,编译后,替换页面中vue
管理的边界
3. beforeMount
- 说明 : 在挂载开始之前被调用 (挂载:可以理解
dom
渲染) - 注意 : 在这里更改数据不会触发
updated
函数 - 场景 : 一般可以在这里做初始数据的获取
4. mounted
- 说明 : 组件已经出现在页面中,数据、真实
dom
都已经处理好了,事件都已经挂载好 - 注意 : 在这里更改数据不会触发
updated
函数 - 场景 : 发送
ajax
或者 操作dom
5. beforeUpdate
- 说明 :
vue
的虚拟dom
机制会重新构建虚拟dom
与上一次的虚拟dom
树利用diff算法进行对比之后重新渲染 - 注意 : 此处获取的数据是更新后的数据,但是获取页面中的
dom
元素是更新之前的 - 场景 : 一般不做操作
6. updated
- 说明 : 数据已经更改完成,
dom
也重新渲染完成, 可以操作更新后的虚拟dom
7. beforeDestroy
- 说明:实例销毁之前调用。在这一步,实例仍然完全可用
- 场景:实例销毁之前,执行清理任务,比如:清除定时器等
8. destroyed
- 说明:
vue
实例销毁后调用。调用后,vue
实例指示的所有东西都会解除绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 - 注意:在执行
destroy
方法后,对data
的改变不会再触发周期函数,此时的vue
实例已经解除了事件监听以及和dom
的绑定,但是dom
结构依然存在。所以对于实时显示的通知型组件,在他destroyed
之前,我们必须手动removeChild()
删除该节点;否则,dom
节点还是存在,影响浏览器性能
执行顺序
父组件
<template>
<div>
<Test :msg="msg"></Test>
</div>
</template>
<script>
import Test from '@/components/test'
export default {
data() {
return {
msg: '父组件存在的消息'
}
},
components: {
Test
},
beforeCreate() {
console.log('============ 父组件页面调用了 beforeCreate ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('msg:', this.msg)
},
created() {
console.log('============ 父组件页面调用了 created ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('msg:', this.msg)
},
beforeMount() {
console.log('============ 父组件页面调用了 beforeMount ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('msg:', this.msg)
},
mounted() {
console.log('============ 父组件页面调用了 mounted ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('msg:', this.msg)
},
beforeUpdate() {
console.log('============ 父组件调用了 beforeUpdate ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('msg:', this.msg)
},
updated() {
console.log('============ 父组件页面调用了 updated ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('msg:', this.msg)
},
beforeDestroy() {
console.log('============ 父组件页面调用了 beforeDestroy ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('msg:', this.msg)
},
destroyed() {
console.log('============ 父组件页面调用了 destroyed ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('msg:', this.msg)
}
}
</script>
子组件
<template>
<div>
哈哈哈 测试
</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
default: '子组件默认的消息'
}
},
data() {
return {
}
},
beforeCreate() {
console.log('============ 子组件调用了 beforeCreate ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('此时子组件获取不到 Props 中 msg 的值,强行获取会报错')
},
created() {
console.log('============ 子组件调用了 created ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('父组件传入的msg:', this.msg)
},
beforeMount() {
console.log('============ 子组件调用了 beforeMount ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('父组件传入的msg:', this.msg)
},
mounted() {
console.log('============ 子组件调用了 mounted ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('父组件传入的msg:', this.msg)
},
beforeUpdate() {
console.log('============ 子组件调用了 beforeUpdate ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('父组件传入的msg:', this.msg)
},
updated() {
console.log('============ 子组件调用了 updated ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('父组件传入的msg:', this.msg)
},
beforeDestroy() {
console.log('============ 子组件调用了 beforeDestroy ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('父组件传入的msg:', this.msg)
},
destoryed() {
console.log('============ 子组件调用了 destoryed ============')
console.log('$el:', this.$el)
console.log('$data:', this.$data)
console.log('父组件传入的msg:', this.msg)
}
}
</script>
执行结果