成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Vue.js源碼——事件機(jī)制

Ethan815 / 1976人閱讀

摘要:的內(nèi)容如下存放事件名以及對(duì)應(yīng)執(zhí)行方法。如果是數(shù)組的時(shí)候,則遞歸,為每一個(gè)成員都綁定上方法這里在注冊(cè)事件的時(shí)候標(biāo)記值也就是個(gè)標(biāo)志位來(lái)表明存在鉤子,而不需要通過(guò)哈希表的方法來(lái)查找是否有鉤子,這樣做可以減少不必要的開(kāi)銷,優(yōu)化性能。

寫在前面

因?yàn)閷?duì)Vue.js很感興趣,而且平時(shí)工作的技術(shù)棧也是Vue.js,這幾個(gè)月花了些時(shí)間研究學(xué)習(xí)了一下Vue.js源碼,并做了總結(jié)與輸出。
文章的原地址:https://github.com/answershuto/learnVue。
在學(xué)習(xí)過(guò)程中,為Vue加上了中文的注釋https://github.com/answershuto/learnVue/tree/master/vue-src,希望可以對(duì)其他想學(xué)習(xí)Vue源碼的小伙伴有所幫助。
可能會(huì)有理解存在偏差的地方,歡迎提issue指出,共同學(xué)習(xí),共同進(jìn)步。

Vue事件API

眾所周知,Vue.js為我們提供了四個(gè)事件API,分別是$on](https://cn.vuejs.org/v2/api/#vm-on-event-callback),[$once,$off](https://cn.vuejs.org/v2/api/#vm-off-event-callback),[$emit。

初始化事件

初始化事件在vm上創(chuàng)建一個(gè)_events對(duì)象,用來(lái)存放事件。_events的內(nèi)容如下:

{
    eventName: [func1, func2, func3]
}

存放事件名以及對(duì)應(yīng)執(zhí)行方法。

/*初始化事件*/
export function initEvents (vm: Component) {
  /*在vm上創(chuàng)建一個(gè)_events對(duì)象,用來(lái)存放事件。*/
  vm._events = Object.create(null)
  /*這個(gè)bool標(biāo)志位來(lái)表明是否存在鉤子,而不需要通過(guò)哈希表的方法來(lái)查找是否有鉤子,這樣做可以減少不必要的開(kāi)銷,優(yōu)化性能。*/
  vm._hasHookEvent = false
  // init parent attached events
  /*初始化父組件attach的事件*/
  const listeners = vm.$options._parentListeners
  if (listeners) {
    updateComponentListeners(vm, listeners)
  }
}
$on

$on方法用來(lái)在vm實(shí)例上監(jiān)聽(tīng)一個(gè)自定義事件,該事件可用$emit觸發(fā)。

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

    /*如果是數(shù)組的時(shí)候,則遞歸$on,為每一個(gè)成員都綁定上方法*/
    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
      /*這里在注冊(cè)事件的時(shí)候標(biāo)記bool值也就是個(gè)標(biāo)志位來(lái)表明存在鉤子,而不需要通過(guò)哈希表的方法來(lái)查找是否有鉤子,這樣做可以減少不必要的開(kāi)銷,優(yōu)化性能。*/
      if (hookRE.test(event)) {
        vm._hasHookEvent = true
      }
    }
    return vm
  }
$once

$once監(jiān)聽(tīng)一個(gè)只能觸發(fā)一次的事件,在觸發(fā)以后會(huì)自動(dòng)移除該事件。

  Vue.prototype.$once = function (event: string, fn: Function): Component {
    const vm: Component = this
    function on () {
      /*在第一次執(zhí)行的時(shí)候?qū)⒃撌录N毀*/
      vm.$off(event, on)
      /*執(zhí)行注冊(cè)的方法*/
      fn.apply(vm, arguments)
    }
    on.fn = fn
    vm.$on(event, on)
    return vm
  }
$off

$off用來(lái)移除自定義事件

Vue.prototype.$off = function (event?: string | Array, fn?: Function): Component {
    const vm: Component = this
    // all
    /*如果不傳參數(shù)則注銷所有事件*/
    if (!arguments.length) {
      vm._events = Object.create(null)
      return vm
    }
    // array of events
    /*如果event是數(shù)組則遞歸注銷事件*/
    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參數(shù)則注銷該event方法下的所有方法*/
    if (arguments.length === 1) {
      vm._events[event] = null
      return vm
    }
    // specific handler
    /*遍歷尋找對(duì)應(yīng)方法并刪除*/
    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用來(lái)觸發(fā)指定的自定義事件。

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) {
      /*將類數(shù)組的對(duì)象轉(zhuǎn)換成數(shù)組*/
      cbs = cbs.length > 1 ? toArray(cbs) : cbs
      const args = toArray(arguments, 1)
      /*遍歷執(zhí)行*/
      for (let i = 0, l = cbs.length; i < l; i++) {
        cbs[i].apply(vm, args)
      }
    }
    return vm
  }
關(guān)于

作者:染陌

Email:answershuto@gmail.com or answershuto@126.com

Github: https://github.com/answershuto

Blog:http://answershuto.github.io/

知乎主頁(yè):https://www.zhihu.com/people/cao-yang-49/activities

知乎專欄:https://zhuanlan.zhihu.com/ranmo

掘金: https://juejin.im/user/58f87ae844d9040069ca7507

osChina:https://my.oschina.net/u/3161824/blog

轉(zhuǎn)載請(qǐng)注明出處,謝謝。

歡迎關(guān)注我的公眾號(hào)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/88728.html

相關(guān)文章

  • vue源碼解析-事件機(jī)制

    摘要:直接寫了組件機(jī)制。今天看了下的關(guān)于事件的機(jī)制。源碼都是基于最新的。綁定了事件回調(diào)函數(shù)的。初始化的時(shí)候,將中的方法代理到的同時(shí)修飾了事件的回調(diào)函數(shù)。對(duì)于事件有兩個(gè)底層的處理邏輯。 上一章沒(méi)什么經(jīng)驗(yàn)。直接寫了組件機(jī)制。感覺(jué)涉及到的東西非常的多,不是很方便講。今天看了下vue的關(guān)于事件的機(jī)制。有一些些體會(huì)。寫出來(lái)。大家一起糾正,分享。源碼都是基于最新的Vue.js v2.3.0。下面我們來(lái)看...

    LuDongWei 評(píng)論0 收藏0
  • Vue.js 源碼學(xué)習(xí)筆記

    摘要:實(shí)際上,我在看代碼的過(guò)程中順手提交了這個(gè),作者眼明手快,當(dāng)天就進(jìn)行了修復(fù),現(xiàn)在最新的代碼里已經(jīng)不是這個(gè)樣子了而且狀態(tài)機(jī)標(biāo)識(shí)由字符串換成了數(shù)字常量,解析更準(zhǔn)確的同時(shí)執(zhí)行效率也會(huì)更高。 最近饒有興致的又把最新版?Vue.js?的源碼學(xué)習(xí)了一下,覺(jué)得真心不錯(cuò),個(gè)人覺(jué)得 Vue.js 的代碼非常之優(yōu)雅而且精辟,作者本身可能無(wú) (bu) 意 (xie) 提及這些。那么,就讓我來(lái)吧:) 程序結(jié)構(gòu)梳...

    darkbaby123 評(píng)論0 收藏0
  • Vue.js 源碼學(xué)習(xí)筆記

    摘要:實(shí)際上,我在看代碼的過(guò)程中順手提交了這個(gè),作者眼明手快,當(dāng)天就進(jìn)行了修復(fù),現(xiàn)在最新的代碼里已經(jīng)不是這個(gè)樣子了而且狀態(tài)機(jī)標(biāo)識(shí)由字符串換成了數(shù)字常量,解析更準(zhǔn)確的同時(shí)執(zhí)行效率也會(huì)更高。 最近饒有興致的又把最新版?Vue.js?的源碼學(xué)習(xí)了一下,覺(jué)得真心不錯(cuò),個(gè)人覺(jué)得 Vue.js 的代碼非常之優(yōu)雅而且精辟,作者本身可能無(wú) (bu) 意 (xie) 提及這些。那么,就讓我來(lái)吧:) 程序結(jié)構(gòu)梳...

    jsdt 評(píng)論0 收藏0
  • vue-router 實(shí)現(xiàn)分析

    摘要:而組件在創(chuàng)建時(shí),又怎么會(huì)去調(diào)用呢這是由于將自身作為一個(gè)插件安裝到了,通過(guò)注冊(cè)了一個(gè)鉤子函數(shù),從而在之后所有的組件創(chuàng)建時(shí)都會(huì)調(diào)用該鉤子函數(shù),給了檢查是否有參數(shù),從而進(jìn)行初始化的機(jī)會(huì)。 vue-router 是 Vue.js 官方的路由庫(kù),本著學(xué)習(xí)的目的,我對(duì) vue-router 的源碼進(jìn)行了閱讀和分析,分享出來(lái)給其他感興趣的同學(xué)做個(gè)參考吧。 參考 源碼:vuejs/vue-route...

    psychola 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<