最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入理解Vue.js源碼之事件機(jī)制

 更新時(shí)間:2017年09月27日 09:53:20   作者:曹陽(yáng)  
本篇文章主要介紹了Vue.js源碼之事件機(jī)制,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

寫(xiě)在前面

因?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<string>, 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<string>, 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
 }

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue3設(shè)置Proxy代理解決跨域問(wèn)題

    Vue3設(shè)置Proxy代理解決跨域問(wèn)題

    這篇文章主要介紹了Vue3設(shè)置Proxy代理解決跨域問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • vue3 elementplus table合并寫(xiě)法

    vue3 elementplus table合并寫(xiě)法

    這篇文章主要介紹了vue3 elementplus table合并寫(xiě)法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • vue router demo詳解

    vue router demo詳解

    這篇文章主要為大家詳細(xì)介紹了vue router demo演示代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Vue3中使用Element-Plus的el-upload組件限制只上傳一個(gè)文件的功能實(shí)現(xiàn)

    Vue3中使用Element-Plus的el-upload組件限制只上傳一個(gè)文件的功能實(shí)現(xiàn)

    在 Vue 3 中使用 Element-Plus 的 el-upload 組件進(jìn)行文件上傳時(shí),有時(shí)候需要限制只能上傳一個(gè)文件,本文將介紹如何通過(guò)配置 el-upload 組件實(shí)現(xiàn)這個(gè)功能,讓你的文件上傳變得更加簡(jiǎn)潔和易用,需要的朋友可以參考下
    2023-10-10
  • petite?vue的使用示例詳解

    petite?vue的使用示例詳解

    這篇文章主要為大家介紹了petite?vue的使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 基于vue實(shí)現(xiàn)循環(huán)滾動(dòng)列表功能

    基于vue實(shí)現(xiàn)循環(huán)滾動(dòng)列表功能

    這篇文章給大家介紹基于vue實(shí)現(xiàn)循環(huán)滾動(dòng)列表功能,給大家介紹了該組件的用法,通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-09-09
  • vue自定義開(kāi)關(guān)組件使用詳解

    vue自定義開(kāi)關(guān)組件使用詳解

    這篇文章主要為大家詳細(xì)介紹了vue自定義開(kāi)關(guān)組件的使用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • vue+elementui 表格分頁(yè)限制最大頁(yè)碼數(shù)的操作代碼

    vue+elementui 表格分頁(yè)限制最大頁(yè)碼數(shù)的操作代碼

    這篇文章主要介紹了vue+elementui 表格分頁(yè)限制最大頁(yè)碼數(shù)的操作代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-08-08
  • Vue?監(jiān)聽(tīng)視頻播放時(shí)長(zhǎng)的實(shí)例代碼

    Vue?監(jiān)聽(tīng)視頻播放時(shí)長(zhǎng)的實(shí)例代碼

    本文介紹了如何通過(guò)源碼實(shí)現(xiàn)對(duì)視頻實(shí)時(shí)時(shí)長(zhǎng)、播放時(shí)長(zhǎng)和暫停時(shí)長(zhǎng)的監(jiān)聽(tīng),詳細(xì)闡述了相關(guān)技術(shù)的應(yīng)用方法,幫助開(kāi)發(fā)者更好地掌握視頻監(jiān)控技術(shù),提高用戶體驗(yàn)
    2024-10-10
  • vue3中refs用法舉例小結(jié)

    vue3中refs用法舉例小結(jié)

    這篇文章主要給大家介紹了關(guān)于vue3中refs用法舉例的相關(guān)資料,Vue.js中的$refs是一個(gè)對(duì)象,它持有已注冊(cè)過(guò)ref特性的所有組件和元素,需要的朋友可以參考下
    2023-08-08

最新評(píng)論

台州市| 开封县| 公主岭市| 万盛区| 车险| 英超| 台东县| 平潭县| 文登市| 青冈县| 阿拉善盟| 鸡西市| 随州市| 高邮市| 塘沽区| 正安县| 松阳县| 贡嘎县| 唐河县| 朝阳区| 确山县| 澳门| 合阳县| 札达县| 阳信县| 融水| 象州县| 库车县| 雷州市| 兴仁县| 大兴区| 伊春市| 古田县| 浦北县| 旬邑县| 海宁市| 兴安县| 开阳县| 内丘县| 山西省| 大宁县|