如何通过 ref 获取子组件或 DOM 元素

113 阅读1分钟

🎯 场景目标

想在父组件中 访问子组件里的 DOM 元素,比如获取 <button> 标签本身。

✅ 第一步:在子组件中定义 ref 并暴露出去

子组件(MyButton.vue)

<template>
  <button ref="buttonRef">按钮</button>
</template>

<script setup lang="ts">
import { ref } from "vue";

// 1️⃣ 创建 ref,用于绑定 DOM 元素
const buttonRef = ref<HTMLButtonElement | null>(null);

// 2️⃣ 暴露这个 ref 给父组件用
defineExpose({
  buttonRef,
});
</script>

buttonRef 是一个响应式引用,指向 <button> 这个真实 DOM 元素。
defineExpose() 是 Vue3 <script setup> 提供的语法,用来暴露子组件内部的属性给父组件访问。

✅ 第二步:在父组件中通过 ref 获取子组件实例

父组件(App.vue 或其他)

<template>
  <!-- 3️⃣ 给子组件加 ref -->
  <MyButton ref="btnRef" />
</template>

<script setup lang="ts">
import { ref, onMounted } from "vue";
import MyButton from "@/components/Button/MyButton.vue";

// 4️⃣ 创建 ref,用来接收子组件实例
const btnRef = ref<InstanceType<typeof MyButton> | null>(null);

// 5️⃣ 组件挂载后访问子组件暴露的 DOM 元素
onMounted(() => {
  const dom = btnRef.value?.buttonRef; // ✅ 注意这里没有 `.value`,因为暴露出来的已经是 HTMLButtonElement
  console.log("子组件内部的 button DOM:", dom);
});
</script>

📌 小结步骤回顾

步骤操作说明
1️⃣子组件中创建 ref 指向 DOMref<HTMLButtonElement>()
2️⃣defineExpose 暴露 ref使父组件能访问
3️⃣父组件中给子组件加 ref<MyButton ref="btnRef" />
4️⃣onMounted 中访问 btnRef.value?.buttonRef得到原生 DOM 元素

🧠 小Tips

  • ref() 创建的是一个响应式引用对象,它有 .value 属性。
  • 但当你通过 defineExpose() 暴露出去时,可以直接访问,不需要 .value.value
  • InstanceType<typeof Component> 是 TS 写法,拿到组件的类型实例。