请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于自定义事件$emit的一个问题

 Vue.prototype.$emit = function (event: string): Component {
    const vm: Component = this
    if (process.env.NODE_ENV !== 'production') {
      const 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}".`
        )
      }
    }
    let cbs = vm._events[event]
    if (cbs) {
      cbs = cbs.length > 1 ? toArray(cbs) : cbs
      const args = toArray(arguments, 1)
      for (let i = 0, l = cbs.length; i < l; i++) {
        try {
          cbs[i].apply(vm, args)
        } catch (e) {
          handleError(e, vm, `event handler for "${event}"`)
        }
      }
    }
    return vm
  }```
$emit派发事件是for循环里调用cbs.apply(vm(子组件实例),args),但是老师为什么你说这是在父组件环境下调用的呢?

正在回答

2回答

首先 $emit 是往当前实例上派发一个事件。
其次,通常我们说组件通讯的时候,子组件想通知父组件的时候,通常会执行 $emit 派发一个事件,但由于我们的子组件是写在父组件中的,那么这个事件侦听函数的执行作用域也就是父组件了。

0 回复 有任何疑惑可以回复我~
  • 提问者 knightBUTnotYONNG #1
    事件侦听函数不就是cbs吗,cbs.apply(子组件实例,arg)不就是指定在子组件的环境里执行吗?
    回复 有任何疑惑可以回复我~ 2019-03-20 18:34:07
  • 提问者 knightBUTnotYONNG #2
    非常感谢!
    回复 有任何疑惑可以回复我~ 2019-03-20 22:22:31
前端工程师666777888 2021-04-20 11:15:25

cbs.apply(vm(子组件实例),args)。

按理说,cbs中的this,确实是子组件实例。

但是vue框架处理了,处理过程如下:

在this.$emit()时,会执行cbs.apply(vm(子组件实例),args),但是此时的cbs是createFnInvoker()函数中的invoker()函数并不是我们写的回调函数。在invoker()函数中,会把cbs指向我们的回调函数,在执行时会变成这样cbs.apply(null,args),已经变成null了。所以cbs中的this还是指向父组件

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信