Nuxt3中如何精准监听slot子组件挂载完成?
解决方案
针对你需要在slot子组件挂载完成后执行GSAP动画的需求,以下是几种基于Nuxt3/Vue3的重构方案,替代MutationObserver:
方案一:监听容器子元素数量变化(无需修改子组件)
利用Vue的响应式监听,追踪父组件容器的子元素数量变化,确保子组件DOM渲染完成后执行方法:
<template> <div> <div ref="el"> <slot /> </div> </div> </template> <script setup> const el = ref(null) function myMethod() { // 你的GSAP移动逻辑,比如: // gsap.to(el.value.children[0], { x: 100, duration: 1 }) } // 监听容器子元素数量,触发后用nextTick确保DOM完全就绪 watch( () => el.value?.children.length, (newLen) => { if (newLen > 0) { nextTick(myMethod) } }, { immediate: true } // 初始化时立即检查一次 ) </script>
原理:子组件的v-if条件满足后,会向父组件的容器中添加DOM元素,此时children.length从0变为大于0,触发watch回调。nextTick确保DOM更新完成,避免GSAP找不到元素的问题。
方案二:子组件主动通知父组件(最可靠)
让子组件在自身渲染完成后,通过自定义事件通知父组件执行方法,这种方式更直接可控:
子组件修改:
<template> <div v-if="currentData"> ... </div> </template> <script setup> const props = defineProps({ items: { type: Array, default: () => [] }, }) const emit = defineEmits(['child-mounted']) const currentData = computed(() => props.items[0]) // 监听currentData,当有值且DOM渲染完成后通知父组件 watch(currentData, (val) => { if (val) { nextTick(() => emit('child-mounted')) } }, { immediate: true }) </script>
父组件使用:
<template> <div> <div ref="el"> <slot @child-mounted="myMethod" /> </div> </div> </template> <script setup> const el = ref(null) function myMethod() { // 你的GSAP逻辑 } </script>
原理:子组件自己知道v-if的触发时机,在数据就绪且DOM挂载完成后,通过emit通知父组件执行动画,完全避免了DOM时机判断的问题。
为什么之前的slot监听无效?
你尝试监听slots.default()的方式不生效,原因是:
slots.default()返回的是VNode数组,Vue的watch默认是浅监听,而VNode的引用不会随子组件v-if的状态变化而改变,所以无法触发回调。- 即使VNode存在,也不代表对应的DOM已经渲染(因为
v-if条件可能还未满足),所以这种方式无法准确判断DOM挂载时机。
内容的提问来源于stack exchange,提问作者Michaël
相关产品推荐
相关产品推荐

