vue2 communicates across multi-layer components - you can use dispatch and broadcast

Introduction

Element dispatch and broadcast are both event-related concepts in JavaScript, but they are somewhat different:
Element dispatch is used to dispatch (ie initiate) customization on a specific HTML element the course of events. Only specific elements will receive these events.
Broadcast is a way of broadcasting an event across the entire page (or document) and calling handlers in all its child elements. In this case, the parent element passes the event to its children until it finds an element that can handle the event.
In Element dispatch, the event will only be processed on the element it is dispatched to. Broadcast will call the handler on all child elements, so on a page with multiple levels of nested elements, there may be multiple elements responding to the same broadcast event.

Recently, in the process of using zfs-ui components (rewriting element), I found that component communication uses dispatch and broadcast methods extensively. Let's take a look at how to implement these two functions.

Code part:

emitter.js

function broadcast(componentName, eventName, params) {
    
    
  this.$children.forEach((child) => {
    
    
    const name = child.$options.componentName;

    if (name === componentName) {
    
    
      child.$emit(...[eventName].concat(params));
    } else {
    
    
      broadcast.apply(child, [componentName, eventName].concat([params]));
    }
  });
}
export default {
    
    
  methods: {
    
    
    dispatch(componentName, eventName, params) {
    
    
      let parent = this.$parent || this.$root;
      let name = parent.$options.componentName;

      while (parent && (!name || name !== componentName)) {
    
    
        parent = parent.$parent;

        if (parent) {
    
    
          name = parent.$options.componentName;
        }
      }
      if (parent) {
    
    
        parent.$emit(...[eventName].concat(params));
      }
    },
    broadcast(componentName, eventName, params) {
    
    
      broadcast.call(this, componentName, eventName, params);
    },
  },
};

Insert image description here

Code analysis:

Both dispatch and broadcast methods require 3 parameters:

  1. componentNameComponent name;
  2. eventName Incident name;
  3. params Parameters passed.

The dispatch method will search all parent components until it finds the component named componentName and calls its emit() event.
The broadcast method traverses all subcomponents of the current component, finds the subcomponent named componentName, and then calls it emit() event.

Usage

Communication between sibling components can well explain the above two events. Assume that the parent component App.vue introduces two child components Hello.vue and Fuck.vue.
If Element is used by chance in your project, you can introduce it in the following way. If you don’t use Element, don’t worry, just copy the emitter.js above and introduce it through mixins. That’s it.

Listen to the message event in App.vue. After receiving the event, the event will be propagated to the relevant components through broadcast and the received parameters.

<template>
  <div id="app">
    <hello></hello>
    <fuck></fuck>
  </div>
</template>

<script>
  import Hello from 'components/Hello'
  import Fuck from 'components/Fuck'
  import Emitter from 'element-ui/lib/mixins/emitter'

  export default {
      
      
    name: 'app',
    componentName: 'ROOT',
    mixins: [Emitter],
    components: {
      
      
      Hello,
      Fuck
    },
    created () {
      
      
      this.$on('message', params => {
      
      
        this.broadcast(params.componentName, params.eventName, params.text)
      })
    }
  }
</script>

The contents of Fuck.vue and Hello.vue are basically the same. Only Fuck.vue is listed below.

import Emitter from 'element-ui/lib/mixins/emitter'
import event from 'mixins/event'

export default {
    
    
  componentName: 'Fuck',
  mixins: [Emitter, event],
  data () {
    
    
    return {
    
    
      name: 'Fuck',
      textarea: '',
      tableData: []
    }
  },
  methods: {
    
    
    submit () {
    
    
      this.communicate('message', {
    
    
        componentName: 'Hello',
        text: this.textarea
      })
      this.textarea = ''
    }
  },
  created () {
    
    
    this.$on('message', text => {
    
    
      this.tableData.push(this.getMessage(text))
    })
  }
}

mixins/event.js

import Emitter from 'element-ui/lib/mixins/emitter'

export default {
    
    
  mixins: [Emitter],
  methods: {
    
    
    communicate (event, params = {
     
     }) {
    
    
      this.dispatch('ROOT', event, Object.assign({
    
    
        eventName: event
      }, params))
    }
  }
}

Fuck.vue listens to the message event, and when a message is received, a new value is added to tableData. The summit method calls the communicate method in event.js and propagates the event to the ROOT component through the dispatch method.

Summary of vue component communication methods

The parent component passes information to the child component using props down
The child component passes information to the parent component using event up
Other relationship types use global for component communication. event bus
Use Vuex to communicate between large SPA components to manage component status
Use dispatch and broadcast in emitter.js under Element for directional event propagation

Guess you like

Origin blog.csdn.net/m0_37680500/article/details/131568281