myEvent

91 阅读1分钟
class myEvent {
  constructor(){
    this.Eventarr= [];
    this.on = this.on.bind(this);
    this.emit = this.emit.bind(this);
    this.off = this.off.bind(this);
    this.once = this.once.bind(this);
  }
  // 添加自定义事件
  on(type,callback){
    // 先判断事件是否已经存在 Eventarr 中
    if( findEventarrIndex(this,type) < 0 ) {
      //创建自定义事件
      let Event = new CustomEvent(type);
      let listenerfun  = () =>{
        //获取触发事件的params
        let params =  this.Eventarr.filter(value => value.type === type)[0].params
        callback(...params);
      }
      //把事件添加到this.Eventarr中
      this.Eventarr.push({Event,type,params:null,once:false,listenerfun});
      //监听自定义事件
      window.addEventListener(type,listenerfun);
    } else{
      throw new Error(`已经定义 ${type} 事件无法重复定义`)
    }
  }
  // 删除自定义事件
  off(type){
    let index = findEventarrIndex(this,type)
    if( index>=0 ) {
      window.removeEventListener(this.Eventarr[index].type, this.Eventarr[index].listenerfun);
      this.Eventarr.splice(index,1);
    }else {
      throw  new Error(`找不带事件 ${type} 无法移除`)
    }
  }
  //调用自定义事件
  emit(type, ...rest){
    let index = findEventarrIndex(this,type)
    if( index >= 0 ){
      this.Eventarr[index].params = rest;
      window.dispatchEvent(this.Eventarr[index].Event);
    } else {
      throw  new Error(type+ '事件未定义')
    }

  }
  once(type,callback){
    // 先判断事件是否已经存在 Eventarr 中
    if( findEventarrIndex(this,type) < 0 ) {
      //创建自定义事件
      let Event = new CustomEvent(type);
      let listenerfun  = () =>{
        //获取触发事件的params
        let index = findEventarrIndex(this,type)
        callback(...this.Eventarr[index].params);
        window.removeEventListener(this.Eventarr[index].type, this.Eventarr[index].listenerfun);
        this.Eventarr.splice(index,1);
      }
      //把事件添加到this.Eventarr中
      this.Eventarr.push({Event,type,params:null,once:true,listenerfun});
      //监听自定义事件
      window.addEventListener(type,listenerfun);
    }else{
      throw new Error(`已经定义 ${type} 事件无法重复定义`)
    }
  }
}
const findEventarrIndex = (vm, type) =>{
  return vm.Eventarr.findIndex(value => value.type === type )
}
const install = (Vue) =>{
  //将实例混入所有组件中
  Vue.prototype.$myEvent = new myEvent()
}
export default {
  install
}