调用Composable无法获取emit事件:确认弹窗onCancel无响应求助
问题
调用Composable生成确认弹窗时,组件实例已正常挂载,但无法通过onCancel获取emit事件。需求是每次需要确认交互时调用该弹窗,相关代码如下:
useModalConfirm.ts
function confirm(props: ModalConfirmProps) { const container = document.createElement('div'); document.body.appendChild(container); const component = createVNode(ModalConfirm, { ...props, // 此处无法触发 :( onCancel: () => { console.log('canceled') } }); render(component, container); return component.component; }
ModalConfirm.vue
<script lang="ts" setup> import {NButton} from "naive-ui"; const emits = defineEmits(["onConfirm", "onCancel"]); export type ModalConfirmProps = { title: string; message: string; confirmButtonText: string, cancelButtonText: string, }; const props = defineProps<ModalConfirmProps>(); const confirm = () => { emits("onConfirm"); }; const cancel = () => { emits("onCancel"); }; </script> <template> <div class="ModalConfirm"> <div class="ModalConfirmContent"> {{ props.title }} {{ props.message }} <NButton @click="cancel" type="error">{{ props.cancelButtonText }}</NButton> <NButton @click="confirm" type="success">{{ props.confirmButtonText }}</NButton> </div> </div> </template>
解决思路
修正事件名匹配问题:Vue 3中,
defineEmits声明的事件名与父组件传递的回调命名需要遵循规范。你当前在子组件里声明的是onCancel/onConfirm事件,但Vue会自动将父组件传递的onXxx格式回调映射为监听xxx事件,导致两者不匹配。修改ModalConfirm.vue的事件声明与触发逻辑:
// 改成不带on前缀的事件名 const emits = defineEmits(["confirm", "cancel"]); const confirm = () => { emits("confirm"); }; const cancel = () => { emits("cancel"); };这样父组件中传递的
onCancel/onConfirm就能正确监听子组件触发的cancel/confirm事件。补充Props类型定义:当前
ModalConfirmProps未包含事件回调的类型,需要补充以避免类型报错:export type ModalConfirmProps = { title: string; message: string; confirmButtonText: string; cancelButtonText: string; onConfirm?: () => void; onCancel?: () => void; };添加DOM清理逻辑:弹窗关闭后记得移除容器元素,避免内存泄漏,可在事件回调中补充:
onCancel: () => { console.log('canceled'); render(null, container); document.body.removeChild(container); }
内容的提问来源于stack exchange,提问作者npl85
相关产品推荐
相关产品推荐

