返回正文
Are you an LLM? You can read better optimized documentation at /zh-CN/blog/2025-10/vue-expose.md for this page in Markdown format
Vue 3 组件暴露 DOM 元素给父组件的方式
🎯 目标
在父组件中通过 <MyButton ref="btnRef" />
拿到子组件内真正的 <button>
元素。
✅ 代码拆解
父组件调用
typescript
<MyButton ref="btnRef" type="danger">默认按钮</MyButton>
const btnRef = ref<InstanceType<typeof MyButton> | null>(null);
onMounted(() => {
console.log(btnRef.value?.buttonRef); // 想访问内部的 button 元素
});
1
2
3
4
5
6
7
2
3
4
5
6
7
子组件内部
ts
const buttonRef = ref<HTMLButtonElement | null>(null);
defineExpose({
buttonRef, // 暴露给外部
});
1
2
3
4
5
2
3
4
5
vue
<!-- 子组件模版 -->
<button
:class="buttonClasses"
:disabled="disable"
:autofocus="autofocus"
:type="nativeType"
ref="buttonRef"
>
<span>
<slot />
</span>
</button>
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
✅ 整体逻辑
buttonRef
是子组件内部绑定的 DOM 元素(即真正的<button>
元素)。defineExpose
用于将buttonRef
暴露给父组件。- 父组件通过
ref="btnRef"
拿到 MyButton 实例,并通过.buttonRef
拿到<button>
。
✅ 实际行为验证
只要以下几点都没错,这就能拿到子组件的 <button>
元素:
- Vue 3 +
<script setup>
中使用defineExpose
; - 子组件中
ref="buttonRef"
确实绑定在<button>
上; - 父组件使用
ref="btnRef"
,然后访问btnRef.value?.buttonRef
。
✅ 示例输出
ts
onMounted(() => {
console.log(btnRef.value?.buttonRef); // HTMLButtonElement | null
});
1
2
3
2
3
你会在控制台看到类似:
html
<button class="xxx" disabled="false" type="button">默认按钮</button>
1
✅ 注意事项
- 确保子组件是用
<script setup>
写的,否则defineExpose
不生效; buttonRef.value
是 DOM 元素,不是组件实例,可以直接.focus()
、.click()
等;- 访问的是
btnRef.value.buttonRef.value
,如果你需要button
原生方法,请多加.value
:
ts
btnRef.value?.buttonRef?.focus(); // 需要加 .value
1
或者:
ts
btnRef.value?.buttonRef?.value?.focus(); // 最稳妥写法
1
VN/A |
本站访客数
--次 本站总访问量
--人次