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

Vue3如何在父元素ref可用时加载子组件?

解决方案

核心原因

Vue 的 $refs 并非响应式数据,仅在组件**挂载完成(mounted 钩子阶段)**后才会被填充。计算属性无法追踪 $refs 的变化,所以不会自动更新;而模板中直接使用 v-if="$refs.refCurrentSlot" 时,首次渲染阶段 $refs 尚未赋值,因此子组件不会加载,直到后续组件更新(比如 mouseover 触发)才会检测到 $refs 存在。


方法一:通过挂载钩子+状态变量控制

利用组件的 mounted 钩子(此时 DOM 已渲染完成,$refs 可用),设置一个状态变量来控制子组件的加载:

<template>
  <div ref="refCurrentSlot" @mouseover="addCssClass" @mouseleave="removeCssClass">
    <div class="tooltipHolder"></div>
  </div>
    
  <Tooltip v-if="isRefReady" :tooltip-holder="() => $refs.refCurrentSlot.querySelector('.tooltipHolder')"></Tooltip>
</template>

<script>
export default {
  data() {
    return {
      isRefReady: false
    }
  },
  mounted() {
    // 组件挂载后,$refs 已被赋值,此时开启子组件加载
    this.isRefReady = true;
    
    // 若父元素依赖异步数据渲染(比如接口返回后才显示),需用 $nextTick 确保 DOM 更新完成
    // this.$nextTick(() => {
    //   this.isRefReady = true;
    // });
  }
}
</script>

方法二:直接绑定目标元素的 ref(更简洁)

无需通过父元素 querySelector,直接给 tooltipHolder 绑定 ref,再传递给子组件:

<template>
  <div ref="refCurrentSlot" @mouseover="addCssClass" @mouseleave="removeCssClass">
    <div ref="tooltipHolder" class="tooltipHolder"></div>
  </div>
    
  <Tooltip v-if="tooltipHolder" :tooltip-holder="() => tooltipHolder"></Tooltip>
</template>

<script>
export default {
  data() {
    return {
      tooltipHolder: null
    }
  },
  mounted() {
    this.tooltipHolder = this.$refs.tooltipHolder;
  }
}
</script>

为什么计算属性无效?

计算属性仅会追踪 Vue 的响应式依赖(比如 data、props 中的变量),而 $refs 不属于响应式数据,因此当 $refs 从 undefined 变为 DOM 元素时,计算属性不会重新计算,自然无法更新状态。

内容的提问来源于stack exchange,提问作者Pad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 02:05:29