关于父组监听子组件的生命周期有两种方式:

方法1:$emit

其实就是在父组件上封装了一个v-on的事件用来监听子组件的事件,只不过事件名和钩子函数同名,当子组件发布时,即执行this.$emit('钩子函数created/mounted',参数)时,在父组件则可以监听到,然后执行回调,使用参考下面的例子

父组件:

<template>
  <div>
    <child-component @mounted="handleDoSomething"></child-component>
  </div>
</template>
<script>
export default Vue.component("HelloWorld", {
 ...
  methods:{
    handleDoSomething(data){
      console.log('监听到子组件生命周期钩子函数mounted时,触发该回调',data)
    }
  },
  components:{
    "child-component":ChildComponent
  }
});
</script>

子组件:

<script>
export default {
   ...
    mounted(){
        this.$emit('mounted','mounted 触发了')
    },
}
</script>

总结:其实就是父子组件通信,事件名和钩子函数相同

缺点:以上方法虽然可行,但每次都需要手动写一次 $emit 触发父组件的事件。

推荐使用:更简单的方式可以在父组件引用子组件时通过 @hook 来监听生命周期。

方法2:@hook 

@hook 方法可以监听子组件的任何的生命周期。子组件不需要发布。直接在父组件中,插入子组件的地方,使用@hook.声明周期函数名="函数名"即可

原理:就是父子组件通信的基础上(方法1),添加@hook,形成了对应生命周期函数的自动发布,方法1每次都是手动执行发布。

实现方式如下:

<template>
  <div>
    <child-component @hook:mounted="handleDoSomething"></child-component>
  </div>
</template>
<script>
export default Vue.component("HelloWorld", {
 ...
  methods:{
    handleDoSomething(data){
      console.log('监听到子组件生命周期钩子函数mounted时,触发该回调',data)
    }
  },
  components:{
    "child-component":ChildComponent
  }
});
</script>

为什么要用@hook

下面浅谈一下,为什么要用@hook,以及hook实现的原理?首先我们先看一个例子

<script>
  export default {
    mounted() {
      this.timer = setInterval(() => { ... }, 1000);
    },
    beforeDestroy() {
      clearInterval(this.timer);
    }
  };
</script>

但是其实更好的做法是:

<script>
  export default {
    mounted() {
      const timer = setInterval(() => { ... }, 1000);
      this.$once('hook:beforeDestroy', () => clearInterval(timer);)
    }
  };
</script>

上面确实可以达到优化或简化代码的效果。比如到多个生命周期的逻辑都非常简单,简单到只有一句时,这个时候就可以考虑将这些代码放在 created 或者 mounted 里,通过这种方式来监听并执行那些简单逻辑。上面的是在组件内的使用。在组件外的使用同样简单。如果在组件外使用,就用父组件上加上@hook就可以达到上面的效果

使用场景

通过监听子组件的生命周期函数来处理业务,例如监听子组件loading,数据渲染到页面的之前让页面 loading。mounted 之后停止 loading。beforeUpdata 时开始 loading。updatad 之后停止 loading,

 官网上对hook 也有描述处理边界情况 — Vue.js 

参考:

@hook 的实现原理可参考https://zhuanlan.zhihu.com/p/142395540

上面是个人理解,写的不好,请指教!

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐