Vue中 $on 和 $emit

2020-04-19  本文已影响0人  HHHHy2019

<html>
  <head>
    <title>$emit 和 $on</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="root">
      <button @click="boost">触发事件</button>
      <!--  => hello vue my params -->
    </div>
    <script>
      new Vue({
        el: '#root',
        data() {
          return {
            message: 'hello vue'
          }
        },
        created() {
          this.$on('my_events', this.handleEvents)
        },
        methods: {
          handleEvents(e) {
            console.log(this.message, e)
          },
          boost() {
            this.$emit('my_events', 'my params')            
          }
        }
      })
    </script>
  </body>
</html>

Vue文档$on的介绍

Vue文档$on的介绍
vm.$on( event, callback )
参数:
{string | Array<string>} event (数组只在 2.2.0+ 中支持)
{Function} callback
用法:
监听当前实例上的自定义事件。事件可以由 vm.$emit 触发。回调函数会接收所有传入事件触发函数的额外参数。
示例:
vm.$on('test', function (msg) {
console.log(msg)
})
vm.$emit('test', 'hi')
// => "hi"


Vue.prototype.$on = function (event, fn) {
  var vm = this //Vue的实例
  if (Array.isArray(event)) {
    //判断是否是event为数组
    for (var i = 0, l = event.length; i < l; i++) {
      vm.$on(event[i], fn)
    }
  } else {
    // 判断实例下是否包含了我们的传入的event,不包含则创建一个新的event数组并且第一个就是传入的fn方法(所以我们一个event可以有多个fn方法,我们会在emit时依次执行我们的fn方法
    ;(vm._events[event] || (vm._events[event] = [])).push(fn)
    // optimize hook:event cost by using a boolean flag marked at registration
      // instead of a hash lookup
      if (hookRE.test(event)) {
        vm._hasHookEvent = true
      }
  }
return vm
  }
  

Vue文档$emit的介绍

Vue文档emit的介绍 vm.emit( eventName, […args] )
参数:
{string} eventName
[...args]
触发当前实例上的事件。附加参数都会传给监听器回调。


  //传入 my_events
Vue.prototype.$emit = function (event) {
  var vm = this
  {
    var lowerCaseEvent = event.toLowerCase() //toLowerCase() 方法用于把字符串转换为小写。   ->my_events
    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 //判断cbs是否为数组
    var args = toArray(arguments, 1) //arguments = ["my_events"=>事件名称,"my params"=>我们传入的参数],args = "my params"
    var info = 'event handler for "' + event + '"'
    for (var i = 0, l = cbs.length; i < l; i++) {
      invokeWithErrorHandling(cbs[i], vm, args, vm, info) // 关键的逻辑使用 try catch 捕获异常,我们在抛出异常时也不会程序中断
    }
  }
  return vm
}


案例可以参考同站的点击这里

上一篇下一篇

猜你喜欢

热点阅读