• 天天用defineEmits宏函数,竟然不知道编译后是vue2的选项式API?


    前言

    我们每天都在使用 defineEmits 宏函数,但是你知道defineEmits 宏函数经过编译后其实就是vue2的选项式API吗?通过回答下面两个问题,我将逐步为你揭秘defineEmits 宏函数的神秘面纱。为什么 Vue 的 defineEmits 宏函数不需要 import 导入就可用?为什么defineEmits的返回值等同于$emit 方法用于在组件中抛出事件?

    举两个例子

    要回答上面提的几个问题我们先来看两个例子是如何声明事件和抛出事件,分别是vue2的选项式语法和vue3的组合式语法。

    我们先来看vue2的选项式语法的例子,options-child.vue文件代码如下:

    <template>
      <button @click="handleClick">放大文字button>
    template>
    
    <script>
    export default {
      name: "options-child",
      emits: ["enlarge-text"],
      methods: {
        handleClick() {
          this.$emit("enlarge-text");
        },
      },
    };
    script>
    

    使用emits选项声明了要抛出的事件"enlarge-text",然后在点击按钮后调用this.$emit方法抛出"enlarge-text"事件。这里的this大家都知道是指向的当前组件的vue实例,所以this.$emit是调用的当前vue实例的$emit方法。大家先记住vue2的选项式语法例子,后面我们讲defineEmits宏函数编译原理时会用。

    我们再来看看vue3的组合式语法的例子,composition-child.vue代码如下:

    <template>
      <button @click="handleClick">放大文字button>
    template>
    
    <script setup lang="ts">
    const emits = defineEmits(["enlarge-text"]);
    function handleClick() {
      emits("enlarge-text");
    }
    script>
    

    在这个例子中我们使用了defineEmits宏函数声明了要抛出的事件"enlarge-text",defineEmits宏函数执行后返回了一个emits函数,然后在点击按钮后使用 emits("enlarge-text")抛出"enlarge-text"事件。

    通过debug搞清楚上面几个问题

    首先我们要搞清楚应该在哪里打断点,在我之前的文章 vue文件是如何编译为js文件 中已经带你搞清楚了将vue文件中的结束标签和