How the child components in Vue pass values to the parent components through custom events

topic description

the chapter on component communication in "Vue.js practice" has an introduction to custom events. The child component"s custom events are notified to the parent component through $emit, while the parent component can listen for the child component"s custom events through v-on . Although I know that it is such a mechanism, I still don"t understand the essence after seeing the following code. I hope the great god can explain it, and it would be better to have a better image.

sources of topics and their own ideas

"Vue.js practice" Chapter 7, Section 7.3 component Communication 7.3.1 Custom events

<my-component @increase="handleGetTotal" @reduce="handleGetTotal"></my-component>

when I see this, I understand it like this: the custom tag my-component defines two custom events, increase and reduce, and the event handlers for both events are handleGetTotal, so I went to the sub-component to check this handler, but found that there was nothing in the methods of the sub-component, only handleIncrease and handleReduce, felt confused here. Then think that this is the parent component listening for these two events through v-on , so the event handler handleGetTotal should be provided by the parent component? Then I saw that I did find it in the methods of the parent component. So, although increase and reduce are events defined by the child components, the corresponding handlers (what do these events do) must be provided by the parent component? Is this understood correctly?

then look at the details of the function:

handleGetTotal: function(total) {
                this.total = total;
                console.log(this);  //Vue
            }

function (total) the total here seems to be coming from the subcomponents, as if through

this.$emit("increase", this.counter);
this.$emit("reduce", this.counter);

but is it spread in this way or not? If so, how does the data of this.counter as a sub-component correspond to the total here in function (total)? When I test function (total), the parameter here is any string, so it corresponds to:

@increase="handleGetTotal"
this.$emit("increase", this.counter);


@reduce="handleGetTotal"
this.$emit("reduce", this.counter);

the data processed by this.counter as a child component is passed back to the function handleGetTotal provided by the parent component. Is that so?
if this is the case, the previous question seems to be solved?

related codes

/ / Please paste the code text below (do not replace the code with pictures)

  <div id="app" v-cloak>
        

:{{total}}

<my-component @increase="handleGetTotal" @reduce="handleGetTotal"></my-component> </div> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script> Vue.component("my-component", { template: `\ <div>\ <button @click="handleIncrease">+1</button>\ <button @click="handleReduce">-1</button>\ </div>`, data: function() { return { counter: 0 } }, methods: { handleIncrease: function() { this.counterPP; this.$emit("increase", this.counter); console.log(this); //VueComponent }, handleReduce: function() { this.counter--; this.$emit("reduce", this.counter); console.log(this); //VueComponent }, } }) var app = new Vue({ el: "-sharpapp", data: { total: 0 }, methods: { handleGetTotal: function(total) { this.total = total; console.log(this); //Vue } } }) </script>
Mar.25,2021

first of all, the event is bound to the child component, whether it is passed by the parent component or the child component itself $on. The
event is essentially passed in as key (increase, reduce), callback (handleGetTotal) when the subcomponent style is created, thus binding their relationship.

Vue each component maintains an events bus,. Below is the Vue source code

Vue.prototype.$on = function (event: string, fn: Function): Component {
    const vm: Component = this
    ;(vm._events[event] || (vm._events[event] = [])).push(fn)
    return vm
  }

 Vue.prototype.$emit = function (event: string): Component {
    const vm: Component = this
    let cbs = vm._events[event]
    if (cbs) {
      cbs = cbs.length > 1 ? toArray(cbs) : cbs
      const args = toArray(arguments, 1)
      for (let i = 0, l = cbs.length; i < l; iPP) {
        cbs[i].apply(vm, args)
      }
    }
    return vm
  }
Menu