vue2.0的生命周期和钩子函数深度解析

生命周期图解

在这里插入图片描述

生命周期的钩子函数(vue1.0 - vue2.0)

vue 1.0 +vue 2.0Description
initbeforeCreate组件实例刚被创建,组件属性计算之前,如 data 属性等
createdcreated组件实例创建完成,属性已绑定,但DOM还未生成,$el 属性还不存在
beforeCompilebeforeMount模板编译 / 挂载之前
compiledmounted模板编译 / 挂载之后
readymounted模板编译 / 挂载之后(不能保证组件已在 document 中)
-beforeUpdate组件更新之后
-updated组件更新之后
-activatedfor keep-alive,组件被激活时调用
-deactivatedfor keep-alive,组件被移除时调用
attached-vm.el 附加到 dom 时调用,直接操纵 vm.$el不会触发这个钩子
datached-dom 中移除 vm.$el 时调用,直接操纵 vm.$el 不会触发这个钩子
beforeDestroybeforeDestroy组件销毁前调用
destroyeddestroyed组件销毁后调用
     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 => 将 elouterHtml 作为模板进行编译 ( 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>

    执行结果
在这里插入图片描述

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半度℃温热

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值