美文网首页
Vue中 $on 和 $emit

Vue中 $on 和 $emit

作者: HHHHy2019 | 来源:发表于2020-04-19 16:39 被阅读0次
  • 事件的定义和消费
  • this.$on('my_events', this.handleEvents) 定义一个监听的(my_events)事件并指定他的执行对象/执行函数(this.handleEvents)
  • this.$emit('my_events', 'my params')消费这个事件
  • 使用on和emit后,我们可以把事件的定义和消费实现逻辑的解耦,可以在父组件监听($on)子组件中直接调用事件($emit)
  • 要强调的一点是:$on$emit事件必须是在一个公共的实例上才能触发!!!
    • 我们可以使用一个空的 Vue 实例作为中央事件总线,比如首先在main.js里新加bus作为一个公共的实例
  • 例:

<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"

  • $on源码

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]
触发当前实例上的事件。附加参数都会传给监听器回调。

  • $emit的源码

  //传入 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
}


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

相关文章

网友评论

      本文标题:Vue中 $on 和 $emit

      本文链接:https://www.haomeiwen.com/subject/yaqvbhtx.html