父组件监听子组件的生命周期 
在 Vue 开发中,父组件有时需要感知子组件的生命周期状态,例如在子组件挂载(mounted)或卸载(unmounted)时触发某些操作。本文将介绍两种常见的实现方法,并探讨它们的使用场景及兼容性。
使用场景 
为什么父组件需要监听子组件生命周期?
- 资源管理
 
在子组件挂载时分配资源,卸载时释放资源,例如订阅、事件绑定或网络请求的清理。
- 状态联动
 
父组件根据子组件的生命周期调整自身状态,比如在子组件挂载后显示某些额外内容,卸载后隐藏相关内容。
- 性能优化
 
控制复杂操作的触发时机,确保子组件就绪后再进行耗时操作。
方法1:使用 emit 
实现原理 
子组件通过 emit 向父组件触发自定义事件,父组件监听这些事件来感知子组件生命周期变化。
示例代码 
父组件代码:
vue
<script setup>
import { ref } from 'vue'
import ChildCom from './ChildCom.vue';
const showChild = ref(false)
function handleChildMounted() {
  alert('子组件mounted钩子触发')
}
function handleChildUnmounted() {
  alert('子组件unmounted钩子触发')
}
</script>
<template>
  <button @click="showChild = true">创建</button>
  <button @click="showChild = false">销毁</button>
  <child-com 
    v-if="showChild" 
    @mounted="handleChildMounted" 
    @unmounted="handleChildUnmounted"
  ></child-com>
</template>子组件代码:
vue
<script setup>
import { defineEmits, onMounted, onUnmounted } from 'vue'
const emits = defineEmits(['mounted', 'unmounted'])
onMounted(() => {
  emits('mounted')
})
onUnmounted(() => {
  emits('unmounted')
})
</script>
<template>
  <div>
    我是子组件
  </div>
</template>跳转到 Vue演练场 查看效果。
方法2:使用 @vue:(Vue3 特性) 
实现原理 
Vue 3 提供了对生命周期钩子事件的直接支持,父组件可以通过 @vue:生命周期名 的方式监听子组件的生命周期。
示例代码 
父组件代码:
vue
<script setup>
import { ref } from 'vue'
import ChildCom from './ChildCom.vue';
const showChild = ref(false)
function handleChildMounted() {
  alert('子组件mounted钩子触发')
}
function handleChildUnmounted() {
  alert('子组件unmounted钩子触发')
}
</script>
<template>
  <button @click="showChild = true">创建</button>
  <button @click="showChild = false">销毁</button>
  <child-com 
    v-if="showChild" 
    @vue:mounted="handleChildMounted" 
    @vue:unmounted="handleChildUnmounted"
  ></child-com>
</template>子组件代码:
vue
<script setup></script>
<template>
  <div>
    我是子组件
  </div>
</template>跳转到 Vue演练场 查看效果。
方法3:使用 @hook:(Vue2 特性) 
在 Vue 2 中,可以使用 @hook:生命周期 来监听子组件的生命周期钩子:
父组件代码:
vue
<template>
  <button @click="showChild = true">创建</button>
  <button @click="showChild = false">销毁</button>
  <child-com 
    v-if="showChild" 
    @hook:mounted="handleChildMounted" 
    @hook:destroyed="handleChildUnmounted"
  ></child-com>
</template>
<script>
import ChildCom from './ChildCom.vue';
export default {
  name: 'ParentCom',
  components: { ChildCom },
  data() {
    return {
      showChild: false
    }
  },
  methods: {
    handleChildMounted() {
      alert('子组件mounted钩子触发')
    },
    handleChildDestroyed() {
      alert('子组件unmounted钩子触发')
    }
  }
}
</script>子组件代码
无需特殊处理,只需保留子组件生命周期钩子即可。
方法对比与兼容性 
| 方法 | 兼容性 | 优势 | 注意事项 | 
|---|---|---|---|
| emit | Vue 2 & 3 | 兼容性好,可自定义事件 | 需要在子组件显式触发事件 | 
| @vue: | Vue 3 | 简单直观,无需子组件额外代码 | 仅支持 Vue 3,Vue 2 中无法使用 | 
| @hook: | Vue 2 | Vue 2 支持生命周期钩子事件 | 仅适用于 Vue 2,Vue 3 中被废弃 | 
总结 
- 兼容性需求高时:推荐使用 
emit方式,自定义事件灵活可控,适用于 Vue 2 和 Vue 3。 - 仅支持 Vue 3 时:优先选择 
@vue:,减少子组件代码,简化实现。 - Vue 2 项目:可直接使用 
@hook:,方便快捷。 
具体选择方法需要根据项目需求和技术栈版本综合考虑。