Kummy's Blog

o(︶︿︶)o { name : 'Kummy' , job : 'Feser' }

vue-自主研发非父子关系组件之间通信的问题

相信很多人都知道解决组件间通信:vuex,今天的主角不是它。

element-ui里解决组件间通信的思路:emitter.js ,但是如果你拿来你会发现它解决的是父子组件之间的通信问题。如果我们通信的组件不是父子关系,emitter.js 就不能做到了。

首页,还是要借鉴前人(emitter)的思路。其实vuex也可以用状态来解决这个问题,我觉得可以不一定要依赖vuex,而且走store繁琐。

我们的需求就是非父子关系之间简单的事件通信

 

现实项目中的一个需求,在“库位列表”的页面操作,通知菜单“库位列表”里的事件。

 

我们再看看,页面组件渲染图,elmenu 和  stockposition 发现它们并不是父子关系,但是它们的共有父亲节点是ElContainer,这是我们的突破口:

 

方案实现思路:我们先找到父亲节点,我定义寻找的父亲节点:app,然后递归遍历子节点,找到通信目标组件,直接上代码 emitter.js:

export default {
    methods: {
      dispatchComponent(componentName, eventName, params) {
        var parent = this.$parent || this.$root , com = null;
        var name = parent.$options.name;
        
        // 找到顶级app父亲节点
        while (parent && (!name || name !== componentName) && name!="app") {
          parent = parent.$parent;
  
          if (parent) {
            name = parent.$options.name;
          }
        }
        
        // 递归遍历子节点,找到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 组件代码

 

 

 

stockposition.vue 组件代码

 

最后效果:

 

posted @ 2018-08-18 12:04  李 维  阅读(643)  评论(0编辑  收藏  举报