在 Vue 3 中,defineExpose 是一个由 <script setup> 语法糖提供的编译时辅助函数,它用于显式地声明一个组件对外暴露的属性、方法或生命周期钩子。这个函数通常在使用 <script setup> 编写的组件内部被调用,以便父组件能够通过 ref 引用访问到这些暴露的成员。
使用场景
当你在一个组件内部使用 <script setup> 时,组件的实例不会像在使用传统 <script> 标签时那样默认暴露给父组件。这意味着,如果你想要从父组件访问子组件的某些方法或属性,你需要显式地使用 defineExpose 来暴露它们。
基本用法
vue复制代码
<script setup>
import { ref, onMounted } from vue;
const count = ref(0);
function increment() {
count.value ;
onMounted(() => {
console.log(Component mounted);
// 使用 defineExpose 暴露 count 和 increment 给父组件
defineExpose({
count,
increment
// 注意:onMounted 生命周期钩子不需要暴露,因为它不会被父组件直接调用
</script>
在上面的例子中,count 和 increment 被暴露给了父组件,而 onMounted 生命周期钩子则没有暴露。父组件可以通过 ref 引用访问到 count 和调用 increment 方法。
注意事项
编译时检查:defineExpose 是在编译时被处理的,这意味着它不会在运行时增加任何性能开销。
类型安全:在使用 TypeScript 时,defineExpose 可以帮助你确保暴露给父组件的成员的类型是正确的。
避免过度暴露:只暴露必要的属性和方法,以避免不必要的复杂性和潜在的安全问题。
与 <script> 的区别:在使用传统的 <script> 标签时,组件的所有属性和方法默认都是暴露的。而在 <script setup> 中,你需要显式地使用 defineExpose 来暴露它们。
父组件访问子组件
在父组件中,你可以通过 ref 引用和 .value 属性来访问子组件暴露的成员:
vue复制代码
<template>
<ChildComponent ref="childRef" />
<button @click="callChildMethod">Call Child Method</button>
</template>
<script setup>
import { ref } from vue;
import ChildComponent from ./ChildComponent.vue;
const childRef = ref(null);
function callChildMethod() {
if (childRef.value) {
childRef.value.increment();
console.log(childRef.value.count);
</script>
在这个例子中,父组件通过 ref 引用访问了子组件的 increment 方法和 count 属性。