Vue3 - defineExpose的使用
·
在 Vue 3 的 <script setup> 语法中,defineExpose 是一个特殊的编译宏,用于显式暴露组件内部的属性或方法,让父组件可以通过 ref 引用 访问到子组件的这些成员。
为什么需要 defineExpose?
在 <script setup> 中,组件的内部状态(如变量、方法)默认是 私有 的,父组件无法直接通过 ref 访问。这是为了封装组件内部实现,避免外部随意修改。
如果父组件需要访问子组件的某些属性或方法,就必须通过 defineExpose 主动暴露。
基本用法
1. 子组件中使用 defineExpose 暴露成员
vue
<!-- 子组件 Child.vue -->
<script setup>
import { ref } from 'vue'
// 内部状态
const count = ref(0)
const name = ref('子组件')
// 内部方法
const increment = () => {
count.value++
}
// 暴露给父组件的成员(对象形式)
defineExpose({
count, // 暴露响应式变量
name, // 暴露响应式变量
increment // 暴露方法
})
</script>
<template>
<div>子组件:count = {{ count }}</div>
</template>
2. 父组件通过 ref 访问子组件暴露的成员
vue
<!-- 父组件 Parent.vue -->
<script setup>
import { ref, onMounted } from 'vue'
import Child from './Child.vue'
// 创建 ref 引用子组件
const childRef = ref(null)
// 子组件挂载后才能访问(确保 ref 已指向子组件实例)
onMounted(() => {
// 访问子组件暴露的属性
console.log(childRef.value.name) // 输出:"子组件"
console.log(childRef.value.count) // 输出:0
// 调用子组件暴露的方法
childRef.value.increment()
console.log(childRef.value.count) // 输出:1
})
</script>
<template>
<Child ref="childRef" />
</template>
注意事项
-
访问时机:
父组件必须在子组件 挂载完成后 才能通过
ref访问暴露的成员(可在onMounted钩子中操作,或在模板中用可选链?.避免初始化报错)。vue
<!-- 模板中安全访问 --> <div>子组件count:{{ childRef?.count }}</div> -
响应式保持:
如果暴露的是
ref或reactive类型的响应式数据,父组件访问时仍能保持响应式(子组件修改后,父组件会自动更新)。 -
仅用于
<script setup>:defineExpose是<script setup>特有的语法,普通的<script>组件(非 setup 语法)不需要它,直接通过this暴露即可。 -
暴露的是 “引用”:
父组件拿到的是子组件内部成员的引用,修改暴露的响应式数据会直接影响子组件(需谨慎操作,避免破坏组件封装性)。
总结
defineExpose 的核心作用是 打破 <script setup> 的默认私有性,让父组件能安全访问子组件的指定成员,适用于需要父子组件紧密交互的场景(如父组件调用子组件方法、获取子组件状态等)。
更多推荐


所有评论(0)