父组件监听子组件的生命周期
在 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:
,方便快捷。
具体选择方法需要根据项目需求和技术栈版本综合考虑。