defineExpose
暴露子组件的方法给父组件(不直接调用父组件方法,但可用于间接通信)虽然这不是直接调用父组件方法的方式,但 defineExpose
可以让父组件通过 ref 访问子组件的方法和属性,从而可能实现一些间接的通信逻辑。
这是 Vue 中最推荐的父子组件通信方式。子组件通过 $emit
触发一个自定义事件,父组件监听这个事件并作出响应。
子组件 (Child.vue
或 Child.tsx
):
<script setup> import { defineEmits } from 'vue'; const emit = defineEmits(['callParentMethod']); function childMethod() { // 子组件内部逻辑 // ... // 调用父组件方法,通过事件触发 emit('callParentMethod', someData); } </script> <template> <button @click="childMethod">Call Parent Method</button> </template>
父组件:
<template> <Child @callParentMethod="parentMethod" /> </template> <script setup> import Child from './Child.vue'; // 或 Child.tsx function parentMethod(dataFromChild: any) { // 处理子组件传递的数据 console.log(dataFromChild); } </script>
provide
和 inject
(适用于跨多层级组件通信)虽然这不是直接调用父组件方法,但 provide
和 inject
可以在组件树中任意位置进行通信。你可以在父组件中使用 provide
提供一个方法或数据,然后在子组件(或任何子组件的子孙组件)中使用 inject
接收它。
父组件:
<script setup> import { provide } from 'vue'; function parentMethod() { // 父组件的方法 } provide('parentMethod', parentMethod); </script>
子组件:
<script setup> import { inject } from 'vue'; const parentMethod = inject('parentMethod') as () => void; function callParent() { if (parentMethod) { parentMethod(); } } </script> <template> <button @click="callParent">Call Parent Method</button> </template>
综上所述,虽然 <script setup>
使得直接访问 $parent
或 $emit
变得不那么直接,但 Vue 提供了其他强大的机制来实现父子组件之间的通信。在这些机制中,通过自定义事件进行通信是最直接和推荐的方式。
总结: