一.主要原理git
我把一些會被多個頁面調用的事件放到一個集合裏面,以事件名稱爲key,以事件及其回調函數的數組爲值。大概的形式以下。數組
events={「event_name1」:[[o11,callback11],[o12,callback12]],"event_name2":[[o21,callback21],[o22,callback22]]}app
而後其餘的頁面就能夠從這個池子(集合)裏面經過事件名稱找到對應的事件元素,拿到他的callback函數,進行調用了。函數
二.主要代碼this
事件總線的主要代碼以下:spa
1 let events = {}; 2 3 const on = function (name, self, callback) { 4 const tuple = [self, callback]; 5 const callbacks = events[name]; 6 if (Array.isArray(callbacks)) { 7 callbacks.push(tuple); 8 } 9 else { 10 events[name] = [tuple]; 11 } 12 } 13 14 const remove = function (name, self) { 15 const callbacks = events[name]; 16 if (Array.isArray(callbacks)) { 17 events[name] = callbacks.filter((tuple) => { 18 return tuple[0] != self; 19 }) 20 } 21 } 22 23 const emit = function (name, data) { 24 const callbacks = events[name]; 25 if (Array.isArray(callbacks)) { 26 callbacks.map((tuple) => { 27 const self = tuple[0]; 28 const callback = tuple[1]; 29 callback.call(self, data); 30 }) 31 } 32 } 33 34 module.exports = { 35 on: on, 36 remove: remove, 37 emit: emit 38 }
首先咱們定義了一個events對象,它的結構就是咱們上面所說的那樣。而後咱們寫了三個函數,分別是on,remove,emit。分別分別表明將事件註冊,事件卸載,還有調用事件。code
在on方法中,咱們先檢查當前name所對應的事件是否已存在(經過Array.isArray方法來判斷其是不是數組,由於當callbacks爲[]或者undifined的時候,該方法返回false).若是不存在,則將當前的tuple置爲二維數組中的第一個數組元素。對象
在remove方法中,咱們先經過name獲取到其對應的二維數組callbacks,仍是先經過Array.isArray判斷該二維數組是否存在,若是存在,開始遍歷該二維數組,而且過濾掉第一個元素爲self的數組。(這邊使用到了數組的filter方法,該方法經過回調函數會保留判斷爲true的元素,剔除掉判斷爲false的元素)。而後咱們把過濾後的二維數組從新賦值給events[name]。這樣就實現了事件的卸載。blog
最重要的是emit函數,這也是咱們作事件總線的主要緣由:咱們一樣經過name來獲取二維數組,而後執行該二維數組中的每個回調函數,此處經過call方法來實現。事件
三.使用方法
1 onShow: function () { 2 const _this = this; 3 const key = app.config.amapkey; 4 const initAmap = new amap.AMapWX({ key: key }); 5 events.on('locationData', this, function (data) { 6 const origin = data.longitude + ',' + data.latitude; 7 const destination = app.globalData.destination; 8 initAmap.getDrivingRoute({ 9 origin: origin, 10 destination: destination, 11 success: function (data) { 12 let points = []; 13 if (data.paths && data.paths[0] && data.paths[0].steps) { 14 const steps = data.paths[0].steps; 15 for (var i = 0; i < steps.length; i++) { 16 const poLen = steps[i].polyline.split(';'); 17 for (var j = 0; j < poLen.length; j++) { 18 points.push({ 19 longitude: parseFloat(poLen[j].split(',')[0]), 20 latitude: parseFloat(poLen[j].split(',')[1]) 21 }) 22 } 23 } 24 } 25 if (data.paths[0] && data.paths[0].distance) { 26 _this.setData({ 27 distance: data.paths[0].distance + '米' 28 }); 29 } 30 _this.setData({ 31 polyline: [{ 32 points: points, 33 color: "#0091ff", 34 width: 1, 35 dottedLine: true 36 }] 37 }); 38 } 39 }) 40 console.log(destination) 41 42 const markersArray = [{ 43 iconPath: '/resources/image/yipin.png', 44 id: 'pickUpAddress', 45 longitude: parseFloat(destination.split(',')[0]), 46 latitude: parseFloat(destination.split(',')[1]), 47 width: 25, 48 height: 25, 49 title: '自提地點', 50 label: { 51 content: '廈門出口加工區\n海景東路18號2樓', 52 bgColor: '#fff', 53 padding: '5', 54 borderRadius: '3' 55 } 56 }, { 57 id: 'myLocation', 58 longitude: data.longitude, 59 latitude: data.latitude, 60 }] 61 _this.setData({ 62 markersArray, markersArray 63 }) 64 }) 65 },
上述代碼的第5行,註冊了一個事件,名稱叫作locationData,而且傳入參數this,指代當前頁面的page對象,還有一個匿名回調函數。
接下來看如何調用這個事件
1 sendLocation: function () { 2 const _this = this; 3 wx.getLocation({ 4 type: 'wgs84', 5 success: function (res) { 6 events.emit('locationData', res); 7 } 8 }) 9 },
調用emit函數,傳入事件名稱locationData,而且參數res(對應回調函數的參數data)
事件銷燬方法以下:
1 onUnload: function () { 2 const _this = this; 3 clearInterval(_this.data.locationTimer) 4 events.remove('locationData', this); 5 },