跳至主要內容

Mr.Cao...大约 2 分钟

emit 和 on方法

emit

_1、emit执行时候是根据传入的参数,遍历出在on方法定义的时候this.events里边的数组找到与当前名称一样的并且执行之,以下代码为vue源码

 Vue.prototype.$emit = function (event) {
      var vm = this;
      {
        var lowerCaseEvent = event.toLowerCase();
        if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
          tip(
            "Event \"" + lowerCaseEvent + "\" is emitted in component " +
            (formatComponentName(vm)) + " but the handler is registered for \"" + event + "\". " +
            "Note that HTML attributes are case-insensitive and you cannot use " +
            "v-on to listen to camelCase events when using in-DOM templates. " +
            "You should probably use \"" + (hyphenate(event)) + "\" instead of \"" + event + "\"."
          );
        }
      }
      var cbs = vm._events[event];
      if (cbs) {
        cbs = cbs.length > 1 ? toArray(cbs) : cbs;
        var args = toArray(arguments, 1);
        var info = "event handler for \"" + event + "\"";
        for (var i = 0, l = cbs.length; i < l; i++) {
          invokeWithErrorHandling(cbs[i], vm, args, vm, info);
        }
      }
      return vm
    };

以上为vue中$emit的源代码

可以看出以上代码是循环执行之前push到events中相同的事件,玄幻调用invokeWithErrorHandling方法,invokeWithErrorHandling源码如下

function invokeWithErrorHandling (
    handler,
    context,
    args,
    vm,
    info
  ) {
    var res;
    try {
      res = args ? handler.apply(context, args) : handler.call(context);
      if (res && !res._isVue && isPromise(res) && !res._handled) {
        res.catch(function (e) { return handleError(e, vm, info + " (Promise/async)"); });
        // issue #9511
        // avoid catch triggering multiple times when nested calls
        res._handled = true;
      }
    } catch (e) {
      handleError(e, vm, info);
    }
    return res
  }

在invokeWithErrorHandling中apply方法执行了自己写的on方法监听的处理事件,由此emit方法与on方法实现闭环

  • 由invokeWithErrorHandling可看出我们即使在我们自定义的on方法的处理程序中添加了retrun返回值 invokeWithErrorHandling中也会返回这个值,但是在emit中执行invokeWithErrorHandling方法的时候也没有变量接受这个返回值,最终会返回vm,因此emit方法最终的返回值也是整个vue实例,而不会返回我们最初定义的返回值

on

1、on方法在初始化的时候实际上是可以监听多个事件的这时候需要传递一个数组过去执行相同的事件函数

this.$on(['myEvents', 'myEvents2'], this.handleEvents) //执行同个方法

_2、on方法在初始化的过程中实际上是push进了this.events对象中,等到emit调用的时候就去遍历出这个方法并且执行,因此一个emit方法可以执行多个events,代码如下

  created() {
    this.$on('myEvents1', this.handleEvents1)
    this.$on('myEvents2', this.handleEvents2)
  },
  methods:{
  	boost(){
      this.$emit("myEvent1","my params1");
      this.$emit("myEvent2","my params2");
    },		
  }
上次编辑于:
贡献者: Caofangshuai
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8