非父子组件通信,我的vue
  IV4cV57K1sFC 2023年11月02日 97 0

一道面试题 最近在看《JavaScript设计模式与开发实践》中的【发布订阅模式和观察者模式】。我不禁想起了上半年面试的时候一个面试官问我的问题:“你在实际项目中是如何处理非父子组件通信的?” 我回答的是:“大型项目的话一般都会用vuex,在一些小场景里会用EventEmitter”。 没想到面试官接着来了一句:“那你能手写代码实现一个简单的EventEmitter吗?”

手写WventEmitter

我想了一下,这主要是使用了emit发事件,用on去监听,还有off销毁事件监听,once实现单次事件处理...等等。考虑到时间紧张,我就只实现了收、发事件,移除监听的功能,有惊无险。。。

其实细想,这个和vue中内置实现的$emit$on是差不多的 且看下面代码:

class EventEmitter{
	constructor() {
	    // 维护事件及监听者
		this.listenners={}
	}
	/**
	 * 注册事件监听者
	 * @param {Object} type 事件类型
	 * @param {Object} cb 回调函数
	 */
	on(type,cb){
		if(!this.listenners[type]){
			this.listenners[type]=[]
		}
		this.listenners[type].push(cb)
	}
	/**
	 * 发布事件
	 * @param {String} type 事件类型
	 * @param {Function} cb 回调函数  
	 */
	emit(type,...args){
		if(this.listenners[type]){
			this.listenners[type].forEach(cb=>{
				cb(...args)
			})
		}
	}
	/**
	 * 移除某个事件的一个监听者
	 * @param {Object} type 事件类型
	 * @param {Object} cb 回调函数
	 */
	off(type,cb){
		if(this.listenners[type]){
			const targetIndex=this.listenners[type].findIndex(item=>item===cb)
			if(targetIndex!==-1){
				this.listenners[type].splice(targetIndex,1)
			}
			if(this.listenners[type].length===0){
				delete this.listenners[type]
			}
		}
	}
	/**
	 * 移除某个事件的所有监听者
	 * @param {Object} type 事件类型
	 */
	offAll(type){
		if(this.listenners[type]){
			delete this.listenners[type]
		}
	}
}

有了这个自己实现的简单版本的EventEmitter,我们就不用依赖第三方库了!

const mxc=new EventEmitter()

mxc.on('mxc',function(address,food){console.log('我饿了,我们取${address}吃${food}!')})
mxc.emit('mxc','南门','小火锅')

对了,这和Vue的:

const ee = new Vue();
ee.$on('chifan', function(address, food) { console.log(`吃饭了,我们去${address}吃${food}!`) })
ee.$emit('chifan', '三食堂', '铁板饭')

可是有异曲同工之妙!

再往下考虑就会发现,EventEmitter就是一个典型的发布订阅模式,实现了事件调度中心。 发布订阅模式中,包含发布者、事件调度中心、订阅者三个角色,我们刚刚实现的EventEmitter的一个实例:mxc,就是一个事件调度中心,发布者和订阅者之间是互不关心的,它们是松散耦合的。它们关注事件本身。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  gYl4rku9YpWY   2024年05月17日   60   0   0 Vue
  JZjRRktyDDvK   2024年05月02日   88   0   0 Vue
  VlNAKfyhjjp9   2024年04月30日   82   0   0 Vue
  JNTrZmaOQEcq   2024年04月30日   58   0   0 Vue
  onf2Mh1AWJAW   2024年05月17日   63   0   0 Vue
  3A8RnFxQCDqM   2024年05月17日   59   0   0 Vue
IV4cV57K1sFC