vue父子组件的生命周期加载顺序,EventBus(事件总线)在父子组件中的调用时机

411 阅读2分钟

前言

由于是一个小项目,所以并没有使用vuex, 而是通过EventBus进行跨组件传值的。
正常情况下父子组件传值是用不到EventBus的,但是公司的实习生采用了其他组件通过EventBus传递给父组件,父组件又通过EventBus传递给子组件(正常情况是:EventBus传给父组件,父组件再通过props传递给子组件), 所以就踩到了了文章标题中调用时机的坑

父子组件初始化渲染生命周期的执行顺序

由于代码较为简单,就不上代码了,直接上浏览器控制台的打印结果结果:

父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted

image.png

父、子组件更新阶段生命周期的执行顺序(四种情况)

单纯父组件更新(从上到下)

父beforeUpdate -> 父updated

image.png

单纯子组件更新(从上到下)

子beforeUpdate -> 子updated

image.png

父组件更新并影响了子组件

父beforeUpdate -> 子beforeUpdate ->子 updated -> 父updated

image.png

父组件更新影响导致子组件的初始化渲染

父beforeUpdate -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父updated

image.png

父子组件销毁阶段生命周期的执行顺序(两种情况)

父组件销毁

父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed

image.png

子组件销毁

子beforeDestroy -> 子destroyed

image.png

介绍完父子组件生命周期加载顺序,接下来看一下EventBus调用时机就好理解了

EventBus使用有以下关键点:

  • 需要先监听$on()、后触发$emit()
  • 两个组件都已经加载完后触发$emit()$on()可以放在mounted()生命周期中

举例父子组件初始化加载

// 父组件
// 一定要在mounted周期中,因为在其他周期中,子组件还没有加载,更别说$on监听了
mounted () {
    this.$eventBus.emit('handle', '爸爸来了')
}

// 子组件
// 根据上边介绍的加载顺序,子组件这里都是可以的,但是太早的话(beforeCreate)还不能访
// 问 this,实际意义不大,作者这里更推荐在 mounted 中监听
mounted () {
    this.$on('handle', res => {
      this.msg = res
      console.log(this.msg)
    )
}

总结

使用EventBus一定要保证先监听$on()、后触发$emit(),这是铁则,剩下的就可以根据自身需求自由发挥了