Heim  >  Artikel  >  Web-Frontend  >  Analyse des Quellcodes des Vue.js-Ereignismechanismus

Analyse des Quellcodes des Vue.js-Ereignismechanismus

小云云
小云云Original
2018-01-30 17:38:371360Durchsuche

Da ich mich sehr für Vue.js interessiere und der Technologie-Stack, an dem ich normalerweise arbeite, auch Vue.js ist, habe ich in den letzten Monaten einige Zeit damit verbracht, den Vue.js-Quellcode zu studieren und eine Zusammenfassung und Ausgabe zu erstellen . In diesem Artikel wird hauptsächlich der Ereignismechanismus des Vue.js-Quellcodes vorgestellt. Der Herausgeber findet ihn recht gut, daher werde ich ihn jetzt mit Ihnen teilen und als Referenz verwenden. Folgen wir dem Herausgeber und schauen wir uns das an. Ich hoffe, es kann allen helfen.

Während des Lernprozesses wurden chinesische Kommentare zu Vue https://github.com/answershuto/learnVue/tree/master/vue-src hinzugefügt. Ich hoffe, dass es anderen Freunden helfen kann, die Vue-Quelle lernen möchten Code hilft.
Es kann zu Abweichungen im Verständnis kommen. Gerne können Sie Probleme ansprechen und darauf hinweisen, um gemeinsam zu lernen und Fortschritte zu erzielen.

Vue Event API

Wie wir alle wissen, stellt uns Vue.js vier Event-APIs zur Verfügung, nämlich $on](https://cn. vuejs.org/v2/api/#vm-on-event-callback), [$once, $off](https://cn.vuejs.org/v2/api/#vm-off-event-callback), [$emit.

Initialisierungsereignis

Das Initialisierungsereignis erstellt ein _events-Objekt auf der VM, um Ereignisse zu speichern. Der Inhalt von _events ist wie folgt:


{
  eventName: [func1, func2, func3]
}

speichert Ereignisnamen und entsprechende Ausführungsmethoden.


/*初始化事件*/
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

Die $on-Methode wird verwendet, um ein benutzerdefiniertes Ereignis auf der VM abzuhören Instanz. Dieses Ereignis kann durch $emit ausgelöst werden.


 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 wartet auf ein Ereignis, das nur einmal ausgelöst werden kann ausgelöst wird, wird das Ereignis automatisch entfernt.


 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 wird verwendet, um benutzerdefinierte Ereignisse zu entfernen


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 wird verwendet, um bestimmte benutzerdefinierte Ereignisse auszulösen.


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
 }

Verwandte Empfehlungen:

Erklärung des Knotenereignismechanismus

PHP-Ereignismechanismus Implementieren

Ereignismechanismus und Blockierung in jq und js

Das obige ist der detaillierte Inhalt vonAnalyse des Quellcodes des Vue.js-Ereignismechanismus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn