You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:26:13