在 Vue 3 中,<script setup>
是 Vue 单文件组件(SFC)的一种编译时语法糖,它允许更简洁地编写组件逻辑,同时保持与 Vue 2 的 <script>
类似的声明性。在 <script setup>
中,可以直接使用 Composition API 的函数(如 ref
、reactive
、computed
等)来定义组件的状态和逻辑,而无需显式地返回对象。
defineExpose
是 <script setup>
中的一个特殊函数,用于显式地声明需要暴露给父组件的属性或方法。在默认情况下,<script setup>
中定义的所有顶层变量和方法都是私有的,不会被父组件通过模板引用 (ref
) 访问到。如果希望某些内容可以被父组件访问,需要使用 defineExpose
来显式地暴露它们。
下面是一个使用 defineExpose
的例子:
<template>
<button @click="increment">Count: {{ count }}</button>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0);
const increment = () => {
count.value++;
};
// 使用 defineExpose 暴露 count 和 increment 给父组件
defineExpose({
count,
increment
});
</script>
在这个例子中,count
是一个响应式引用,用于存储按钮的点击次数,而 increment
是一个方法,用于增加 count
的值。通过 defineExpose
,我们显式地将这两个属性和方法暴露给父组件,使得父组件可以通过模板引用访问它们。
在父组件中,可以这样使用模板引用访问子组件的 count
和 increment
:
<template>
//使用ref定义<ChildComponent>组件的实例,用来获取组件里面的数据
<ChildComponent ref="childRef" />
<button @click="callChildIncrement">Call Child Increment</button>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const childRef = ref(null);
const callChildIncrement = () => {
if (childRef.value) {
childRef.value.increment(); // 调用子组件的 increment 方法 <ChildComponent>组件
console.log(childRef.value.count); // 访问子组件的 count 属性
}
};
</script>
在这个父组件中,我们创建了一个对子组件的引用 childRef
,并通过这个引用来调用子组件的 increment
方法并访问 count
属性。注意,由于我们在子组件中使用了 defineExpose
来暴露 count
和 increment
,所以我们可以直接在父组件中通过 childRef.value
来访问它们。
如果没有使用 defineExpose
,父组件是无法通过模板引用访问到子组件中定义的 count
和 increment
的,因为它们默认是私有的。