Vue3 + TypeScript 父组件点击按钮触发子组件事件方法
在 Vue 3 和 TypeScript 中,父组件触发子组件事件方法主要有两种方式:使用模板引用(ref) 或 通过自定义事件(emit)。下面是两种方法的详细实现:
方法 1:使用模板引用(Ref)直接调用子组件方法(推荐)
子组件 ChildComponent.vue
vue
复制
下载
<template><div><p>子组件被触发次数: {{ count }}</p></div> </template><script setup lang="ts"> import { ref } from 'vue';const count = ref(0);// 暴露给父组件的方法 const triggerChildMethod = () => {count.value++;console.log('子组件方法被触发'); };// 使用 defineExpose 暴露方法 defineExpose({triggerChildMethod }); </script>
父组件 ParentComponent.vue
vue
复制
下载
<template><div><button @click="handleClick">父组件按钮</button><ChildComponent ref="childRef" /></div> </template><script setup lang="ts"> import { ref } from 'vue'; import ChildComponent from './ChildComponent.vue';// 定义子组件的 Ref 类型 const childRef = ref<InstanceType<typeof ChildComponent> | null>(null);const handleClick = () => {if (childRef.value) {childRef.value.triggerChildMethod(); // 直接调用子组件方法} }; </script>
方法 2:通过自定义事件(Emit)
子组件 ChildComponent.vue
vue
复制
下载
<template><div><p>子组件被触发次数: {{ count }}</p></div> </template><script setup lang="ts"> import { ref } from 'vue';const count = ref(0);// 定义内部方法(不暴露给父组件) const internalMethod = () => {count.value++;console.log('子组件方法被触发'); };// 监听父组件传来的事件名(例如 "trigger-child") defineEmits<{(e: 'trigger-child'): void; }>();// 暴露方法(可选,如果父组件需要通过 ref 调用) defineExpose({ internalMethod }); </script>
父组件 ParentComponent.vue
vue
复制
下载
<template><div><button @click="$refs.childRef?.internalMethod()">方式1: Ref 调用</button><button @click="emitEvent">方式2: 事件触发</button><ChildComponent ref="childRef" @trigger-child="childRef?.internalMethod()" /></div> </template><script setup lang="ts"> import { ref } from 'vue'; import ChildComponent from './ChildComponent.vue';const childRef = ref<InstanceType<typeof ChildComponent> | null>(null);const emitEvent = () => {// 通过事件触发子组件内部逻辑childRef.value?.$emit('trigger-child'); }; </script>
关键点说明:
-
使用
defineExpose
子组件需显式暴露方法,父组件才能通过ref
直接调用。 -
TypeScript 类型安全
ts
复制
下载
const childRef = ref<InstanceType<typeof ChildComponent> | null>(null);
确保调用子组件方法时有完整的类型提示。
-
两种方式选择:
-
Ref 直调:适合直接操作子组件
-
自定义事件:适合解耦场景(子组件自行响应事件)
-
-
注意事项:
-
避免过度使用
ref
破坏组件封装性 -
事件驱动方式更符合 Vue 的数据流原则
-
完整工作流程:
-
子组件用
defineExpose
暴露方法 -
父组件声明
ref
并关联子组件 -
父组件按钮点击时通过
childRef.value.methodName()
调用 -
子组件方法执行并更新状态
根据你的项目结构选择合适的方式即可实现父子组件通信。