vue3学习笔记之emit

35,141 阅读1分钟

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

在vue3中emit的使用方式与vue2有哪些区别?vue3中emit的正确姿势是什么?...

回顾vue2中的emit

在vue2中,子组件想要将自定义事件向上级透传的方式就是this.$emit(<changName>, payload)

child.vue

<template>
<div>
  <button @click="onEmit"> 子组件透传事件 </button>
</div>
</template>
<script>
export default {
  methods: {
    onEmit() {
      this.$emit("on-change", "hi~");
    }
  }
}
</script>

parent.vue

<template>
<div>
  < child @on-change="onChildChange" />
</div>
</template>
<script>
import Child from "./Child.vue";
export default {
  components: {
    Child
  },
  methods: {
    onChildChange(v) {
      console.log(v); // hi~
    }
  }
}
</script>

以上就是vue2 中常见的emit使用方式。关键点就是子组件依赖this.$emit透传,父组件使用子组件并v-on指定子组件透传事件Name.

vue3的emit($emit, emits-options)

setup()中的$emit

在setup()的this 是不指向当前实例的(this为undefined),如果想使用使用$emit的功能,需要借助setup(props, context)中的context;

context会暴露三个组件的property;

export default {
  setup(props, context) {
    // Attribute (非响应式对象)
    console.log(context.attrs)

    // 插槽 (非响应式对象)
    console.log(context.slots)

    // 触发事件 (方法)
    console.log(context.emit)
  }
}

在这里我们需要使用context.emit;如下的🌰

child.vue

<template>
  <div>
    <button @click="clickBtn" class="btn-item">hi~</button>
  </div>
</template>
<script>
import { defineComponent } from 'vue'
export default defineComponent({
  setup (props, ctx) {
    const clickBtn = () => {
      ctx.emit("on-change", "hi~");
    };
    return { clickBtn}
  }
})
</script>

parent.vue

<template>
  <div>
    <emit-child @on-change="emitFn" />
  </div>
</template>

<script>
import { defineComponent } from 'vue'
import EmitChild from "./Child.vue"
export default defineComponent({
  components: {
    EmitChild
  },
  setup () {
    const emitFn = v => {
      console.log(v);
    }
    return { emitFn }
  }
})
</script>

效果图: image

这里说一下如果触发的事件名与原生事件名同名(如 click)会出现问题: 自定义事件与原生事件都会触发 为此将代码略微修改后测试

// child.vue
  const clickBtn = () => {
    ctx.emit("click", "hi~");
  };
// parent.vue
<emit-child @click="emitFn" />

效果图 image 该问题如何解决呢?清往下看

emits-option

详细的文档说明,可以左转链接

在这里简单做一下总结

  1. emits是记录了当前组件的事件列表
  2. 类型: Array | Object
  3. 若为Object增加emit事件的校验(返回值应是boolean),
  4. 可以解决自定义事件名与原生事件相同导致事件多次执行问题(上述)
  5. emits无论是数组或者对象用法最终都会将事件给传递出去,数组或对象的使用只是为了记录实例中的emit事件,或者是验证事件中的参数