实现组件通信的方式:1.EvenBus,2.$emit方式
1.实现简陋版EvenBus:
class mybus {
constructor() {
this.eventObj = {};
}
$on (name, fn) {
if (!this.eventObj[name]) {
this.eventObj[name] = [];
}
this.eventObj[name].push(fn);
}
$emit (name, ...args) {
if (this.eventObj[name]) {
this.eventObj[name].forEach(fn => {
fn(...args);
});
}
}
}
let bn = new mybus
bn.$on('sendmessage', (msg, b) => {
console.log(msg, b);
})
bn.$emit('sendmessage', { a: 1, b: 2 }, 26)
2.通过组件name作为组件唯一标识,实现伪$emit
/**
* 用于向下级指定组件 广播事件并传递数据 (前提:子组件已经通过$on监听该事件)
* @param {组件name} componentName
* @param {事件名称} eventName
* @param {参数载荷} params
*/
function broadcast (componentName, eventName, params) {
this.$children.forEach(child => {
const name = child.$options.name;
if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params));
} else {
broadcast.apply(child, [componentName, eventName].concat([params]));
}
});
}
export default {
data () {
return {
}
},
methods: {
broadcast (componentName, eventName, params) {
broadcast.call(this, componentName, eventName, params);
},
/**
* 用于向上级指定组件 广播事件并传递数据 (前提:父组件已经通过$on监听该事件)
* @param {组件name} componentName
* @param {事件名称} eventName
* @param {参数载荷} params
*/
dispatch (componentName, eventName, params) {
let parent = this.$parent || this.$root;
let name = parent.$options.name;
while (parent && (!name || name !== componentName)) {
parent = parent.$parent;
if (parent) {
name = parent.$options.name;
}
}
if (parent) {
parent.$emit.apply(parent, [eventName].concat(params));
}
},
// 向上级发送数据
emitCatch (compomentName, eventName, payload) {
let parent = this.$parent || this.$root
let name = parent.$options.name
while (name && name !== compomentName) {
parent = parent.$parent
if (parent) {
name = parent.$options.name
}
}
if (parent) {
parent.$emit.apply(parent, [eventName].concat(payload))
}
}
},
}