【组件通信】vue3+ts子组件emit方法在父组件中未触发

213 阅读1分钟

vue3+ts中子组件注册的两个emit方法,点击事件btnclick在父组件中正常,然后一个接收消息的事件rollback,没触发。

子组件:

<button @click="handleEmit">点击</button>
...
const emit = defineEmits(['receivemsg', 'btnclick']);
...
//正常触发
const handleEmit = () => {
  emit('btnclick', '111')
};
//接收socket消息
const onMessage = (msgEvent: any) => {
    //收到服务器信息,心跳重置并发送
    startHeartbeat();
    const msg = msgEvent.data;

    if (msg.indexOf('pong') > 0) {
        return;
    }
    ElNotification.warning({
        title: '消息提醒',
        dangerouslyUseHTMLString: true,
        message: `您有一条来自${JSON.parse(msg).data.name}的新消息,请及时处理`,
        offset: 60,
    });
    emit('receivemsg', msg);
};


父组件:

<global-websocket uri="/admin/ws/info" ref="socketComponent" @receivemsg="receivemsg" @btnclick="handleBtnEmit" />
...

// 引入组件
const GlobalWebsocket = defineAsyncComponent(() => import('/@/components/Websocket/index.vue'));
const socketComponent = ref();
//子组件的emit方法 这个正常
const handleBtnEmit = (data: any) => {
    console.log(111, data);
};
//这个没打印
const receivemsg = (data: any) => {
    console.log(111, data);
};

产生原因:

在 Vue 3 中使用 TypeScript (tsx 或 .vue 文件中的 <script lang="ts">),子组件通过 defineEmits 定义的 emit 事件在父组件中未触发通常有以下几种可能的原因:

  1. 异步组件的加载:你正在使用 defineAsyncComponent 来异步加载子组件。如果子组件在父组件尝试监听事件之前还没有加载完成,那么父组件是无法接收到事件的。
  2. 事件名拼写错误:检查子组件中 emit 调用的事件名 'btnclick' 是否与父组件中监听的事件名完全一致(包括大小写)。
  3. 子组件内部问题:确保 handleEmit 方法确实被调用了,并且 emit 函数是可用的(没有被覆盖或改变)。
  4. Vue 开发者工具:使用 Vue 开发者工具来检查事件是否从子组件正确发出。
  5. Vue 3 的 Composition API:如果你正在使用 Composition API,确保 setup 函数中的 emit 是通过 defineEmits 正确定义的。