Vue中 emit(defineEmits) 的一些坑

97 阅读1分钟

1.先看两段代码

  1. 子组件
<script setup>
const emit = defineEmits(['confirm'])
function child() {
      emit('confirm'); // 触发事件
      console.log(2); // 这会在父组件的 confirm 函数执行后打印
    }
</script>

<template>
 <button @click="child">Click me</button>
</template>

2.父组件

<script setup>
import Child from "@/views/HelloWorld/components/Child.vue";
async function confirm() {
      console.log(1); // 这会在子组件的 emit 调用后立即打印
    }
</script>

<template>
    <Child @confirm="confirm"/>
</template>

执行代码可以看出来父组件的 console.log 先执行 (结果:1 2)

2.改一下父组件代码

  1. 父组件
<script setup>
import Child from "@/views/HelloWorld/components/Child.vue";
async function confirm() {
     console.log(1); 
    await  new Promise((resolve)=> {
        setTimeout(() => {
          resolve()
        }, 0);
      })
      console.log(3); 
    }
</script>

<template>
    <Child @confirm="confirm"/>
</template>

(结果:1 2 3)

总结

  • 子组件emit,父组件立刻执行监听的回调函数
    • 若父组件不存在阻塞的异步函数,则先执行父组件的回调,最后执行emit 剩余函数
    • 若父组件存在阻塞的异步函数,则父组件执行直至回调挂起,然后执行emit 剩余函数,最后等待父组件的从挂起回到事件执行队列,执行剩余父组件剩余函数