vuejs2.x里面的事件总线大家因该都会用了
let eventBus = new new()
然后我们就就可以获取到实例上的 o n , on, on,emit,$off事件了,从而就可以进行组件特别是兄弟组件之间的数据传递了!今天我们不讲怎么使用这个,主要记录下怎么实现这个总线的原理!不多说,上代码
发布—订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状
态发生改变时,所有依赖于它的对象都将得到通知。在 JavaScript 开发中,我们一般用事件模型
来替代传统的发布—订阅模式。
var salesOffices = {} //发布对象
salesOffices.clinetLists = []
//订阅事件
salesOffices.listen = function (fn) {
this.clinetLists.push(fn)
}
//发布事件
salesOffices.trigger = function () {
this.clinetLists.forEach((fn) => fn())
}
salesOffices.listen(function () {
console.log('1')
})
salesOffices.listen(function () {
console.log('2')
})
salesOffices.trigger()
上面的方法不能传递参数,我们再改进下
var salesOffices = {} //发布对象
salesOffices.clinetLists = []
//订阅事件
salesOffices.listen = function (fn) {
this.clinetLists.push(fn)
}
//发布事件
salesOffices.trigger = function () {
this.clinetLists.forEach((fn) => fn.apply(this, arguments)) //打印传进来的参数
}
salesOffices.listen(function (price, size) {
console.log('1', price, size)
})
salesOffices.listen(function (price, size) {
console.log('2', price, size)
})
salesOffices.trigger(30000, 200)
salesOffices.trigger(2000, 88)
var salesOffices = {} //发布对象
salesOffices.clinetLists = {} //缓存列表
//订阅事件
salesOffices.listen = function (key, fn) {
if (!this.clinetLists[key]) {
this.clinetLists[key] = [fn]
}
this.clinetLists[key].push(fn)
}
//发布事件
salesOffices.trigger = function () {
var key = [].shift.call(arguments),
fns = this.clinetLists[key]
if (!fns || fns.length == 0) {
return false
}
for (var i = 0, fn; (fn = fns[i++]); ) {
fn.apply(null, arguments)
}
}
//订阅消息
salesOffices.listen('squareMeter88', function (price, size) {
// 小明订阅 88 平方米房子的消息
console.log('价格= ' + price, '面积:' + size) // 输出: 2000000
})
salesOffices.listen('squareMeter100', function (price, size) {
// 小红订阅 110 平方米房子的消息
console.log('价格= ' + price, '面积:' + size) // 输出: 3000000
})
salesOffices.trigger('squareMeter88', 2000000, 88)
salesOffices.trigger('squareMeter100', 3000000, 100)
/* 自动注册发布订阅模式 */
var events = {
clinetLists: {}, //必须味object
listen: function (key, fn) {
if (!this.clinetLists[key]) {
this.clinetLists[key] = [fn]
}
this.clinetLists[key].push(fn)
},
trigger: function () {
var key = [].shift.call(arguments),
fns = this.clinetLists[key]
if (!fns || fns.length == 0) {
return false
}
for (var i = 0, fn; (fn = fns[i++]); ) {
fn.apply(null, arguments)
}
}
}
上面还没有取消订阅的方法,我们再改进下
var events = {
clinetLists: {}, //必须味object
listen: function (key, fn) {
if (!this.clinetLists[key]) {
this.clinetLists[key] = [fn]
}
this.clinetLists[key].push(fn)
},
trigger: function () {
var key = [].shift.call(arguments),
fns = this.clinetLists[key]
if (!fns || fns.length == 0) {
return false
}
for (var i = 0, fn; (fn = fns[i++]); ) {
fn.apply(null, arguments)
}
}
}
然后再测试下
var sales = {}
installEvent(sales)
let fn1, fn2
sales.listen(
'squareMeter88',
(fn1 = function (price) {
// 小明订阅消息
console.log('价格= ' + price)
})
)
sales.listen(
'squareMeter100',
(fn2 = function (price) {
// 小红订阅消息
console.log('价格= ' + price)
})
)
sales.trigger('squareMeter88', 2000) // 2000
sales.trigger('squareMeter100', 3000) // 3000
sales.remove('squareMeter88', fn1)
sales.trigger('squareMeter88', 2000) // 2000
sales.trigger('squareMeter100', 3000) // 3000
// 价格= 2000000 面积:88
// 价格= 3000000 面积:100
// 价格= 2000
// 价格= 3000
// 取消订阅成功fn1
// 价格= 3000
最终版的发布订阅模式
/* 全局的发布订阅模式 */
var Event = (function () {
var clinetLists = {},
on,
emit,
off,
remove
on = function (key, fn) {
if (!clinetLists[key]) {
clinetLists[key] = [fn]
}
clinetLists[key].push(fn)
}
emit = function () {
var key = [].shift.call(arguments),
fns = clinetLists[key]
if (!fns && fns.length == 0) {
return false
}
for (var i = 0, fn; (fn = fns[i++]); ) {
fn.apply(null, arguments)
}
}
remove = function (key, fn) {
var fns = clinetLists[key]
if (!fns) {
return false
}
if (!fn) {
fns && (fns.length = 0)
} else {
for (var l = fns.length - 1, _fn; (_fn = fns[l--]); ) {
if (fn == _fn) {
fns.splice(l, 1)
}
}
}
}
return {
on,
emit,
off
}
})()
Event.on('test1', function (price) {
// 小红订阅消息
console.log('价格= ' + price) // 输出:'价格=2000000'
})
Event.on('test1', function (price) {
// 小红订阅消息
console.log('价格= ' + price) // 输出:'价格=2000000'
})
Event.on('test2', function (price) {
// 小红订阅消息
console.log('价格= ' + price) // 输出:'价格=2000000'
})
Event.emit('test2', 500)
Event.emit('test1', 500)
今天的总结就到此结束,有不足的地方可以提出大家互相学习~~~