vuejs源码分析之全局API(vm.$off)

vuejs源码分析之全局API(vm.$off)_第1张图片

vue在初始化的时候会给vue对象本身挂载一些全局的api。今天我们一个一个来看这些api。

vm.$off方法

这个方法是用来移除自定义事件监听器。
他的用法

vm.$off(event, calback)

第一个参数event取值可以是string字符串,也可以是Array也就是说既可以删除一个事件,也可以删除指定的多个。

第二个参数callback是Function函数类型。

也就是说移除这个事件对应的函数。

  • 如果没有提供参数,则移除所有的事件监听器
  • 如果只提供了事件,则移除该事件所有的监听器
  • 如果同时提供了事件与回调,则只移除这个回调的监听器

没有参数的情况下

没有参数我们需要移除所有事件的监听器。代码如下:

Vue.prototype.$off = function ( 
    event?: string | Array,
    fn?: Function): Component {
    const vm: Component = this
    // 移除所有事件的监听器
    if (!arguments.length) {
        vm._events = Object.create(null)
        return vm
    }
    return vm;
}

从代码我们看出来当arguments.length为0的时候,说明没有任何参数,这时就需要移除所有的事件监听器,因此我们重置了vm._events属性。
vm._evnents属性存储了所有事件。所以将vm.events重置为初始状态就等于将所有事件都移除了。

第一个参数是数组的情况

vm.$off的第一个参数event支持数组,所以接下来需要处理event参数为数组的情况。

其处理逻辑很简单,只需要将数组遍历一遍,然后数组中每一项依次调用vm.$off即可。

 Vue.prototype.$off = function (
    event?: string | Array,
    fn?: Function
  ): Component {
    const vm: Component = this
    // 移除所有事件的监听器
    if (!arguments.length) {
        vm._events = Object.create(null);
        return vm;
    }

    // 新增代码
    if (Array.isArray(event)) {
        for (let i = 0, l = event.length; i < l; i++) {
            this.$off(event[i], fn);
        }
        return vm;
    }

    return vm;
}

在上面代码中,event参数是数组时,遍历它并依次调用this. o f f 。代码中 t h i s . off。代码中this. off。代码中this.off和vm.$off是同一个方法,vm是this的别名。

有事件名,但是没有回调函数

则移除该事件所有监听器。将this._events中将event重置为空即可。

const cbs = vm._events[event];
if (!cbs) {
    return vm;
}

// 移除该事件的所有监听器
if (arguments.length === 1) {
    vm._events[event] = null
    return vm;
}

事件和回调都有的情况

只需要使用参数提供的事件名从vm._events上取出事件列表。然后从列表中找到与参数提供回调函数相同的那个函数,并将它从列表中移除。

 if (fn) {
      const cbs = vm._events[event];
      let cb;
      let i = cbs.length;
      while (i--) {
          cb = cb[i];
          if (cb === fn || cb.fn === fn) {
              cbs.splice(i, 1);
              break;
          }
      }
  }

你可能感兴趣的:(vue.js,前端,javascript)