摘要:中的事件相關的方法扒一扒的源碼,中事件相關的方法,無非這幾個,。通過方法掛在的原型上,本文就是通過解讀的源碼,實現一個簡單的事件處理中心類。全局定義一個屬性,存儲事件通過方法在的原型上掛載方法接下來,我們來實現方法。
vue中的事件相關的方法
扒一扒Vue的源碼,vue中事件相關的方法,無非這幾個,vm.$on, vm.$off, vm.$once, vm.$emit。通過eventsMinxin方法掛在Vue的原型上,本文就是通過解讀vue的源碼,實現一個簡單的事件處理中心類 EventBus。
首先,我們來回顧下這幾個方法的用法:
vm.$on( event, callback )參數:
{string | Array
{Function} callback
vm.$once( event, callback )參數:
{string} event
{Function} callback
vm.$off( [event, callback] )參數:
{string | Array
{Function} [callback]
vm.$emit( eventName, […args] )參數:
{string} eventName
[...args]
觸發當前實例上的事件。附加參數都會傳給監聽器回調。
實現一個EventBus首先,我們先定義一個全局的類EventBus。
function EventCenter() { // 全局定義一個_events屬性,存儲事件 this._events = Object.create(null); } // 通過eventMixin方法在EventCenter的原型上掛載方法 eventMixin(EventCenter); export default EventCenter;
接下來,我們來實現eventMixin方法。
export default function eventMixin(EventCenter) { EventCenter.prototype.on = function(event, fn) {...} EventCenter.prototype.off = function(event, fn) {...} EventCenter.prototype.once = function(event, fn) {...} EventCenter.prototype.once = function(event) {...} }
ec.on( event, fn ), event值可以為數組和字符串,fn為事件觸發時的回調函數
EventCenter.prototyoe.on = function(event, fn) { const ec = this; if (Array.isArray(event)) { for (let i = 0; i < event.length; i++) { ec.on(event[i], fn) } } else { (ec._events[event] || (ec._events[event] = [])).push(fn); } }
ec.off( event, fn ), event值可以為數組和字符串,fn為事件觸發時的回調函數
EventCenter.prototyoe.on = function(event, fn) { const ec = this; // 判斷如果不傳參數, 則移除所有事件 if (!arguments.length) { ec._events = Object.create(null); } // event為數組時,遍歷移除事件 if (Array.isArray(event)) { for(let i = 0; i < event.length; i++) { ec.off(event[i], fn); } return ec; } const cbs = ec._events[event]; // 回調不存在 直接返回 if (!cbs) { return ec; } // cbs為一個或者fn不存在,ec._events[event] = null, 直接移除 if (arguments.length === 1) { ec._events[event] = null; return ec; } if (!fn) { ec._events[event] = null; return ec; } // 否則,遍歷cbs,移除cbs中為fn的回調函數 let cb; let i = cbs.length; // 從后向前遍歷,移除當前監聽器時,不會影響未遍歷過的監聽器的位置。 while (i--) { cb = cbs[i]; if (cb === fn || cb.fn === fn) { cbs.splice(i, 1); break; } } return ec; }
ec.once( event, fn ), event值可以為字符串,fn為事件觸發時的回調函數
const ec = this; // 自定義一個_on方法,先解綁_on, 然后通過調用apply方法執行fn。 function _on() { ec.off(event, _on); fn.apply(ec, arguments); } // 這句暫時沒看懂,等之后查了資料補充 _on.fn = fn; ec.on(event, _on); return ec;
ec.emit( event, ...args ), event值可以為字符串,...args為調用時的傳參
EventCenter.prototype.emit = function(event) { const ec = this; let cbs = ec._events[event]; if (cbs) { // 拿到傳參 const args = Array.from(arguments).slice(1); for(let i = 0; i < cbs.length; i++) { try { cbs[i].apply(ec, args); } catch(e) { new Error("error"); } } } return ec; }
至此,一個簡單的事件中心就完成了。
參考: vue源碼 core/instance/events.js
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106400.html
摘要:一父組件通過的方式向子組件傳遞數據,而通過子組件可以向父組件通信。而且只讀,不可被修改,所有修改都會失效并警告。 之前寫了一篇關于vue面試總結的文章, 有不少網友提出組件之間通信方式還有很多, 這篇文章便是專門總結組件之間通信的 vue是數據驅動視圖更新的框架, 所以對于vue來說組件間的數據通信非常重要,那么組件之間如何進行數據通信的呢?首先我們需要知道在vue中組件之間存在什么樣...
摘要:所有的高階抽象組件是通過定義選項來聲明的。所以一般在生命周期或者中,需要用實例的方法清除可當你有多個時,就需要重復性勞動銷毀這件事兒。更多的配置請看雙端開啟開啟壓縮的好處是什么可以減小文件體積,傳輸速度更快。本文目錄 接口模塊處理 Vue組件動態注冊 頁面性能調試:Hiper Vue高階組件封裝 性能優化:eventBus封裝 webpack插件:真香 本文項目基于Vue-Cli3,想知...
摘要:主要是看這是從上個頁面傳來的數據這一行數據的輸出次數情況來判斷事件觸發次數。總結所以,如果想要用來進行頁面組件之間的數據傳遞,需要注意亮點,組件事件應在生命周期內。其次,組件內的記得要銷毀。 轉載于簡書 原文鏈接:https://www.jianshu.com/p/fde...一開始的需求是這樣子的,我為了實現兩個頁面組件之間的數據傳遞,假設我有頁面A,點擊頁面A上的某一個按鈕之后,頁...
摘要:同時有一種特殊的實現方案。組件之間傳值有這么幾種數據傳遞方式,和特殊的。在所有實例中使用其進行數據的通信。雙多方使用同名事件進行溝通。數據非長效數據,無法保存,只在后生效。這樣約定的好處是,我們能夠記錄所有中發生的改變。 前言 最近碰到了比較多的關于vue的eventBus的問題,之前定技術選型的時候也被問到了,vuex和eventBus的使用范圍。所以簡單的寫一下。同時有一種特殊的實...
閱讀 3873·2021-09-23 11:51
閱讀 3064·2021-09-22 15:59
閱讀 862·2021-09-09 11:37
閱讀 2068·2021-09-08 09:45
閱讀 1266·2019-08-30 15:54
閱讀 2060·2019-08-30 15:53
閱讀 491·2019-08-29 12:12
閱讀 3286·2019-08-29 11:15