在Vue中组件通信 用 $emit,这个只涉及到 父子组件之间的通信,如果是多个组件之间,层级关系比较复杂的情况下,怎么办呢。对了,还有 vuex eventBus 等。今天自己写了一个 任意组件之间的通信,是任意组件,而且只需要几行代码即可,超级好用。
注意:严格意义上来说应该叫 事件的分发,也就是所谓的 订阅者模式,间接的事件组件的通信,目前这个demo是一对多的,其实也是可以一对一,只需要在数据上面做些文章即可
直接上代码
const commonMsg={
data:{}, // 存储数据 logistic 模块 name age 等每个字段
registerEvents:(modulName,propetyName,cb)=>{ // 注册监听事件 modulName :模块名字 propeyName:模块中的属性名字 cb:回调事件
//1.将 modulName propetyName ,cb 都存起来
if(!commonMsg.data[modulName]){
commonMsg.data[modulName] = {};
}
if(!commonMsg.data[modulName][propetyName]){
commonMsg.data[modulName][propetyName] = []; //里面全部是 callBack
}
commonMsg.data[modulName][propetyName].push(cb);
},
// 发送事件的方法 ,发送消息的名字,modelData ,消息体
sendEvents:(modulName,modelData)=>{
if(commonMsg.data[modulName]){ //如果事件存在,发送消息
let keys = Object.keys(commonMsg.data[modulName]);
keys.forEach(key=>{
let listCbs = commonMsg.data[modulName][key];
listCbs.forEach(cb=>{
cb(modelData)
})
})
}
}
}
export {commonMsg};
用法:
- 注册事件 ,若一个组件 需要 监听 abc(事件的名字)
commonMsg.registerEvents('abc','efg',(dataBack)=>{
self.acceptData = dataBack;
console.log('i am back data is',dataBack);
- 发出事件 与 数据 ,一个组件 ,发出事件的名字,加上 data,需要传递的数据
sendEvent(){
commonMsg.sendEvents('abc',{name:'xiao ming',age:80})
},
- 之前注册的那些组件就会 拿到 发出的数据
** 阐述**
主要是定义一个 model,里面存上 注册过来的事件(存在 data中),propetyName这个属性暂时没有用到,但是如果你要实现 一对一的传递数据,这个参数就有用了,可以存上 注册事件的名字,然后在发事件的时候,查找你需要 发送给 那个组件
data中主要存 key:listCallback .listCallback 这个callBack 才是重点。重点是用了js 异步的原理,当有对应的事件与数据发送过来的时候。会找到 所有的 callBack数组,全部回调,这样就实现了,数据的传递
gitdemo地址,获取请猛戳这里,顺手给个star