美文网首页
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