Skip to content

父组件监听子组件的生命周期

Vue 开发中,父组件有时需要感知子组件的生命周期状态,例如在子组件挂载(mounted)或卸载(unmounted)时触发某些操作。本文将介绍两种常见的实现方法,并探讨它们的使用场景及兼容性。

使用场景

为什么父组件需要监听子组件生命周期?

  1. 资源管理

在子组件挂载时分配资源,卸载时释放资源,例如订阅、事件绑定或网络请求的清理。

  1. 状态联动

父组件根据子组件的生命周期调整自身状态,比如在子组件挂载后显示某些额外内容,卸载后隐藏相关内容。

  1. 性能优化

控制复杂操作的触发时机,确保子组件就绪后再进行耗时操作。

方法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>

子组件代码

无需特殊处理,只需保留子组件生命周期钩子即可。

方法对比与兼容性

方法兼容性优势注意事项
emitVue 2 & 3兼容性好,可自定义事件需要在子组件显式触发事件
@vue:Vue 3简单直观,无需子组件额外代码仅支持 Vue 3,Vue 2 中无法使用
@hook:Vue 2Vue 2 支持生命周期钩子事件仅适用于 Vue 2,Vue 3 中被废弃

总结

  • 兼容性需求高时:推荐使用 emit 方式,自定义事件灵活可控,适用于 Vue 2 和 Vue 3。
  • 仅支持 Vue 3 时:优先选择 @vue:,减少子组件代码,简化实现。
  • Vue 2 项目:可直接使用 @hook:,方便快捷。

具体选择方法需要根据项目需求和技术栈版本综合考虑。