vue3 defineExpose的使用
子组件
//子组价
<template><view class="box">子组件num值:{{num}}</view>
</template><script setup>import {ref} from "vue";const num=ref(100);const fn = ()=>{console.log('我是方法');}defineExpose({num,fn})
</script>
父组件
//父组价
<template><view><child-defineExpose ref="child"></child-defineExpose></view>
</template><script setup>import {onMounted, ref} from "vue";const child=ref(null);onMounted(()=>{console.log(child.value.num,child.value.fn())})
</script>
简介:
在 Vue 3 的组合式 API 中,defineExpose
是一个用于向父组件暴露内部属性和方法的宏。这在使用 <script setup>
语法时特别有用,因为默认情况下,使用 <script setup>
的组件是封闭的,即父组件无法访问子组件的内部状态。通过 defineExpose
,你可以选择性地暴露需要被外部访问的属性或方法。
关键点说明
-
仅暴露显式声明的属性
- 未在
defineExpose
中列出的属性和方法对父组件不可见。 - 例如,上面的
message
属性未被暴露,父组件无法访问。
- 未在
-
类型支持(TypeScript)
- 可以通过泛型参数为暴露的属性和方法提供类型定义:
typescript
defineExpose<{count: number;increment: () => void; }>();
- 可以通过泛型参数为暴露的属性和方法提供类型定义:
-
与非
<script setup>
组件的区别- 在普通的
export default
组件中,直接通过this
暴露属性和方法,无需defineExpose
。
- 在普通的
应用场景
- 父组件需要控制子组件的状态(如获取表单组件的值、触发子组件的动画)。
- 封装可复用组件时,明确暴露可被外部调用的 API。
注意事项
- 避免过度暴露:仅暴露真正需要被外部访问的属性和方法,保持组件的封装性。
- 响应式问题:暴露的
ref
在父组件中访问时会自动解包(即直接访问.value
)。 - 测试考量:过度依赖组件间的直接引用可能导致测试困难,优先考虑通过事件或状态管理共享数据。
通过 defineExpose
,你可以在保持 Vue 3 组合式 API 简洁性的同时,灵活地实现组件间的交互。