vue 跨组件自定义事件调度处理功能

天涯浪子 提交于 2020-07-26 02:01:49

vue 的 emit 和mixins 两个特性是这篇文章的基础,当然抛开vue 也可以直接使用全局调用实现,所以这块不做讨论

先看效果,合并一个mixin 然后就可以处理事件监听了

 

step 1、编写一个简单mixin 实现事件接收调度处理管理功能

export default {
  created() {
    //定义一个自定义事件 toLowerCase 是为了躲避vue的坑
    this.$on("NotifyChildComReSize".toLowerCase(), this.EVENT_RESIZE_HANDLE);
  },
  data() {
    return {
      events: new Map(),//这里监听自定义事件和回调函数
      EVENT_RESIZE: "EVENT_RESIZE"//事件监听名称 类似 CLICK
    }
  },
  methods: {
    //这是一个 resize 事件的调度处理函数
    EVENT_RESIZE_HANDLE(size) {
      //获取已经注册的监听事件
      let resizeFunS = this.events.get(this.EVENT_RESIZE);
      if (Array.isArray(resizeFunS)) {
        resizeFunS.forEach(func => {
          func.call(this, size);//直接回调 并把 通过自定义事件得到的size 回传给回调函数
        })
      }
    },
    //添加一个事件监听
    addEvent(eventName, func) {
      let targetEventFunS = this.events.get(eventName);
      targetEventFunS = targetEventFunS ||[];
      targetEventFunS.push( func);
      this.events.set(eventName,targetEventFunS);
    },
    //注销事件所有监听
    offEvent(eventName) {
      this.events.set(eventName, []);
    }
  }, destroyed() {
    //销毁一个自定义事件
    this.$off("NotifyChildComReSize".toLowerCase(), this.EVENT_RESIZE_HANDLE);
  }
}

step 2、原始事件触发,可以在任意一级父组件里通过 自己实现动态计算监听组件的大小变化,这块是功能驱动的基础,此处只是抛砖引玉,当然你可以把他设计为一个怪兽被秒掉的通知,也可以设计成你每100万个用户注册成功的通知,实现逻辑由您定

   listenComResize() {
        let intervalTime = 1000;//检测和通知时间间隔,为了避免resize过程中的连续变化导致连续调用
        this.clientHeight = this.$el.parentNode.clientHeight;
        this.scrollHeight = this.$el.parentNode.scrollHeight;
        this.refreshSetInterval = setInterval(() => {
          this.clientHeight = this.$el.parentNode.clientHeight;
          this.scrollHeight = this.$el.parentNode.scrollHeight;
          let clientHeight = this.$el.parentNode.clientHeight;
          let clientWidth = this.$el.parentNode.clientWidth;
          let curTime = new Date().getTime();

          //判断  【(curTime - this.refreshTime) > intervalTime】这句是为了避免通知太过频繁
          if (this.lastHeight != 0 && this.lastWidth != 0 && (clientHeight != this.lastHeight || clientWidth != this.lastWidth) && (curTime - this.refreshTime) > intervalTime) {
           
            this.lastHeight = clientHeight;
            this.lastWidth = clientWidth;
            this.refreshTime = curTime;
            //这块####很~!!重要!!!!@@  ->>>通知到>>>>>>>Mixin
            this.$emit("NotifyChildComReSize".toLowerCase())

          } else if (clientHeight != this.lastHeight || clientWidth != this.lastWidth) {
            this.lastHeight = clientHeight;
            this.lastWidth = clientWidth;
          }
          this.clientHeight = Math.floor(this.clientHeight - 1);
        }, intervalTime);
        this.clientHeight = Math.floor(this.clientHeight - 1);
      }

    },

step 3:注册事件 ,并处理监听

export default {
   mixins:[comEvent],//合并mixin 得到事件监听处理的通知
   mounted(){
     this.addEvent(this.EVENT_RESIZE,this.resizeCall);//注册一个resize事件
   },
   methods:{
     resizeCall(size){
        console.log(size);//输出获得的值
     },
     offResizeCall(){
        this.offEvent(this.EVENT_RESIZE,this.resizeCall);//注销resize事件
     }
   }
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!