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 风格的通信方式。
总结: