>웹 프론트엔드 >JS 튜토리얼 >Vue.js 이벤트 메커니즘 소스 코드 분석

Vue.js 이벤트 메커니즘 소스 코드 분석

小云云
小云云원래의
2018-01-30 17:38:371413검색

저는 Vue.js에 관심이 많고 주로 작업하는 기술 스택이 Vue.js이기 때문에 지난 몇 달 동안 시간을 ​​내어 Vue.js 소스 코드를 공부하고 요약 및 출력을 만들었습니다. 이 글은 주로 Vue.js 소스 코드의 이벤트 메커니즘을 소개합니다. 편집자는 이것이 꽤 좋다고 생각하므로 지금 공유하고 참고용으로 제공하겠습니다. 편집자를 따라가서 모두에게 도움이 되기를 바랍니다.

학습 과정에서 Vue https://github.com/answershuto/learnVue/tree/master/vue-src에 중국어 댓글이 추가되었습니다. Vue 소스 코드를 배우고 싶은 다른 친구들에게 도움이 되길 바랍니다.
이해에 차이가 있을 수 있습니다. 문제를 제기하고 지적하여 함께 배우고 발전해 나가는 것을 환영합니다.

Vue Event API

우리 모두 알고 있듯이 Vue.js는 $on이라는 네 가지 이벤트 API를 제공합니다](https://cn.vuejs.org/v2/api/#vm-on-event -콜백), [$한 번, $off](https://cn.vuejs.org/v2/api/#vm-off-event-callback), [$emit.

초기화 이벤트

초기화 이벤트는 이벤트를 저장하기 위해 VM에 _events 객체를 생성합니다. _events의 내용은 다음과 같습니다.


{
  eventName: [func1, func2, func3]
}

에는 이벤트 이름과 해당 실행 방법이 저장됩니다.


/*初始化事件*/
export function initEvents (vm: Component) {
 /*在vm上创建一个_events对象,用来存放事件。*/
 vm._events = Object.create(null)
 /*这个bool标志位来表明是否存在钩子,而不需要通过哈希表的方法来查找是否有钩子,这样做可以减少不必要的开销,优化性能。*/
 vm._hasHookEvent = false
 // init parent attached events
 /*初始化父组件attach的事件*/
 const listeners = vm.$options._parentListeners
 if (listeners) {
  updateComponentListeners(vm, listeners)
 }
}

$on

$on 메소드는 $emit에 의해 트리거될 수 있는 VM 인스턴스의 사용자 정의 이벤트를 수신하는 데 사용됩니다.


 Vue.prototype.$on = function (event: string | Array<string>, fn: Function): Component {
  const vm: Component = this

  /*如果是数组的时候,则递归$on,为每一个成员都绑定上方法*/
  if (Array.isArray(event)) {
   for (let i = 0, l = event.length; i < l; i++) {
    this.$on(event[i], fn)
   }
  } else {
   (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
   /*这里在注册事件的时候标记bool值也就是个标志位来表明存在钩子,而不需要通过哈希表的方法来查找是否有钩子,这样做可以减少不必要的开销,优化性能。*/
   if (hookRE.test(event)) {
    vm._hasHookEvent = true
   }
  }
  return vm
 }

$once

$once는 한 번만 트리거될 수 있는 이벤트를 수신하고 이벤트가 트리거된 후에 자동으로 이벤트를 제거합니다.


 Vue.prototype.$once = function (event: string, fn: Function): Component {
  const vm: Component = this
  function on () {
   /*在第一次执行的时候将该事件销毁*/
   vm.$off(event, on)
   /*执行注册的方法*/
   fn.apply(vm, arguments)
  }
  on.fn = fn
  vm.$on(event, on)
  return vm
 }

$off

$off는 사용자 정의 이벤트를 제거하는 데 사용됩니다.


Vue.prototype.$off = function (event?: string | Array<string>, fn?: Function): Component {
  const vm: Component = this
  // all
  /*如果不传参数则注销所有事件*/
  if (!arguments.length) {
   vm._events = Object.create(null)
   return vm
  }
  // array of events
  /*如果event是数组则递归注销事件*/
  if (Array.isArray(event)) {
   for (let i = 0, l = event.length; i < l; i++) {
    this.$off(event[i], fn)
   }
   return vm
  }
  // specific event
  const cbs = vm._events[event]
  /*Github:https://github.com/answershuto*/
  /*本身不存在该事件则直接返回*/
  if (!cbs) {
   return vm
  }
  /*如果只传了event参数则注销该event方法下的所有方法*/
  if (arguments.length === 1) {
   vm._events[event] = null
   return vm
  }
  // specific handler
  /*遍历寻找对应方法并删除*/
  let cb
  let i = cbs.length
  while (i--) {
   cb = cbs[i]
   if (cb === fn || cb.fn === fn) {
    cbs.splice(i, 1)
    break
   }
  }
  return vm
 }

$emit

$emit은 지정된 사용자 정의 이벤트를 트리거하는 데 사용됩니다.


Vue.prototype.$emit = function (event: string): Component {
  const vm: Component = this
  if (process.env.NODE_ENV !== &#39;production&#39;) {
   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++) {
    cbs[i].apply(vm, args)
   }
  }
  return vm
 }

관련 권장 사항:

노드 이벤트 메커니즘 설명

PHP 이벤트 메커니즘 구현

jq 및 js의 이벤트 메커니즘 및 차단

위 내용은 Vue.js 이벤트 메커니즘 소스 코드 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.