var vm = new Vue({
sockets:{
connect: function(){
console.log('socket connected')
},
customEmit: function(val){
console.log('this method was fired by the socket server. eg: io.emit("customEmit", data)')
}
},
methods: {
clickButton: function(val){
// $socket is socket.io-client instance
this.$socket.emit('emit_method', val);
}
}
})
Emitter.js
Emitter.js主要是写了一个Emitter对象,该对象提供了三个方法:
addListener
addListener(label, callback, vm) {
// 回调函数类型是回调函数才对
if(typeof callback == 'function'){
// 这里就很常见的写法了,判断map中是否已经注册过该事件了
// 如果没有,就初始化该事件映射的值为空数组,方便以后直接存入回调函数
// 反之,直接将回调函数放入数组即可
this.listeners.has(label) || this.listeners.set(label, []);
this.listeners.get(label).push({callback: callback, vm: vm}); return true
}
return false
}
其实很常规啦,实现发布订阅者模式或者观察者模式代码的同学都很清楚这段代码的意思。Emiiter用一个map来存储事件以及它对应的回调事件数组。这段代码先判断map中是否之前已经存储过了该事件,如果没有,初始化该事件对应的值为空数组,然后将当前的回调函数,压进去,反之,直接压进去。
removeListener
if (listeners && listeners.length) {
index = listeners.reduce((i, listener, index) => {
return (typeof listener.callback == 'function' && listener.callback === callback && listener.vm == vm) ?
i = index :
i;
}, -1); if (index > -1) {
listeners.splice(index, 1);
this.listeners.set(label, listeners);
return true;
}
}
return false;
这里也很简单啦,获取该事件对应的回调数组。如果不为空,就去寻找需要移除的回调,找到后,直接删除,然后将新的回调数组覆盖原来的那个就可以了
emit
if (listeners && listeners.length) {
listeners.forEach((listener) => {
listener.callback.call(listener.vm,...args)
});
return true;
}
return false;这里就是监听到事件后,执行该事件对应的回调函数,注意这里的call,因为监听到事件后我们可能要修改下vue实例的数据或者调用一些方法,用过vue的同学都知道我们都是this.xxx来调用的,所以一定得将回调函数的this指向vue实例,这也是为什么存回调事件时也要把vue实例存下来的原因。










