vue-Independent research and development of communication problems between non-parent-child relationship components

I believe that many people know to solve the communication between components: vuex, today's protagonist is not it.

The idea of ​​​​solving communication between components in element-ui: emitter.js, but if you bring it, you will find that it solves the communication problem between parent and child components. If the components we communicate with are not in a parent-child relationship, emitter.js can't do it.

The homepage still needs to learn from the ideas of the predecessors (emitter). In fact, vuex can also use state to solve this problem. I think it is not necessary to rely on vuex, and it is cumbersome to go to the store.

What we need is simple event communication between non-parent-child relationships

 

A requirement in a real project, operate on the page of "Location List", and notify the events in the menu "Location List".

 

Let's take a look at the page component rendering diagram, elmenu and stockposition find that they are not parent-child relationships, but their common parent node is ElContainer, which is our breakthrough:

 

Solution implementation idea: we first find the parent node, I define the parent node we are looking for: app, then recursively traverse the child nodes, find the communication target component, and directly code emitter.js:

export default {
    methods: {
      dispatchComponent(componentName, eventName, params) {
        var parent = this.$parent || this.$root , com = null;
        var name = parent.$options.name;
        
        // find the top-level app parent node 
        while (parent && (!name || name !== componentName) && name!="app" ) {
          parent = parent.$parent;
  
          if (parent) {
            name = parent.$options.name;
          }
        }
        
        // Recursively traverse child nodes and find componentName 
        let recursiveChild = (parent) => {
            parent.$children.filter(child=>{
                if(child.$options.name==componentName) {
                  com = child;
                } else {
                  recursiveChild(child);
                }
            })
        }
        
        recursiveChild(parent);
       
        if (com) {
          com.$emit.apply(com, [eventName].concat(params));
        }
      }
    }
}

 

elmenu.vue component code

 

 

 

stockposition.vue component code

 

Final effect:

 

Reprinted in: https://www.cnblogs.com/Kummy/p/9496763.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324151232&siteId=291194637