“This is the second day of my participation in the Gwen Challenge in November. See details: The Last Gwen Challenge in 2021”

How is EMIT used in VUE3 different from vue2? What is the correct posture for EMIT in VUE3? .

Review emit in VUe2

In VUe2, this.$emit(

, payload) is the way a child component wants to transmit a custom event to its parent.

child.vue

<template>
<div>
  <button @click="onEmit">Child components pass through events</button>
</div>
</template>
<script>
export default {
  methods: {
    onEmit() {
      this.$emit("on-change"."hi~"); }}}</script>

Copy the code

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>

Copy the code

This is how emit is commonly used in VUe2. The key point is that the child component relies on this.$emit passthrough. The parent component uses the child component and v-on specifies the child passthrough event Name.

Vue3 emit ($emit, emits – options)

In the setup () $emit

This in setup() does not refer to the current instance (this is undefined). If you want to use the functionality of $emit, you need to use the context in setup(props, context);

Context exposes three component properties;

export default {
  setup(props, context) {
    // Attribute (non-responsive object)
    console.log(context.attrs)

    // slot (non-responsive object)
    console.log(context.slots)

    // Trigger event (method)
    console.log(context.emit)
  }
}
Copy the code

Here we need to use context.emit; The following 🌰

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>
Copy the code

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>

Copy the code

Effect:

Note that there is a problem with triggering an event with the same name as a native event (such as click) : both custom and native events are triggered to test the code slightly

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

renderingHow can this problem be solved? To look down

emits-option

For detailed documentation, turn left to link

Here’s a quick summary

  1. emits is a list of events that record the current component
  2. Type: Array | Object
  3. Add emit event validation to Object (return value should beboolean),
  4. Can solve the problem that custom event names are the same as native events, causing the event to execute multiple times (above)
  5. emits Either array or object usage will eventually pass the event, either to record the EMIT event in the instance, or to validate the parameters in the event