defineExpose 暴露方法在 Vue 3 中,你可以使用 defineExpose 宏来显式地指定哪些 properties 或 methods 应该被暴露给模板和父组件。这在使用 <script setup> 时特别有用。
子组件 (ChildComponent.vue):
<script setup>
import { defineExpose } from 'vue';
const internalMethod = () => {
console.log('这是子组件的内部方法');
};
// 暴露给父组件的方法
const exposedMethod = () => {
console.log('这是暴露给父组件的方法');
};
defineExpose({
exposedMethod
});
</script>
<template>
<div>子组件</div>
</template>
父组件:
在父组件中,你可以通过 ref 引用子组件,并调用其暴露的方法。
<template>
<ChildComponent ref="childRef" />
<button @click="callChildMethod">调用子组件方法</button>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const childRef = ref(null);
const callChildMethod = () => {
if (childRef.value) {
childRef.value.exposedMethod();
}
};
</script>
defineEmits 发送事件另一种常用的方法是,子组件不直接暴露方法给父组件,而是通过发送事件来与父组件通信。
子组件 (ChildComponent.vue):
<script setup>
import { defineEmits } from 'vue';
const emit = defineEmits(['internal-event']);
const triggerEvent = () => {
emit('internal-event', '来自子组件的数据');
};
</script>
<template>
<button @click="triggerEvent">触发事件</button>
</template>
父组件:
<template>
<ChildComponent @internal-event="handleInternalEvent" />
</template>
<script setup>
const handleInternalEvent = (data: string) => {
console.log(data); // 来自子组件的数据
};
</script>
这两种方法各有优缺点,选择哪种取决于你的具体需求和偏好。defineExpose 更直接地允许父组件调用子组件的方法,而事件通信则是一种更解耦、更 Vue 风格的通信方式。
总结:
