- Vue 中使用
$on
都毒、$emit
一般用來使用兄弟組件中的參數(shù)傳遞,其原理就是使用了訂閱發(fā)布模式
Vue 的例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 中發(fā)布訂閱模式</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// Vue 的實(shí)例
let vm = new Vue()
// 訂閱事件
vm.$on('change', (val) => {
console.log('change1 ---->', val)
})
vm.$on('change', (val) => {
console.log('change2 ---->', val)
})
// 發(fā)布事件
vm.$emit('change', 'hello')
console.log(vm.$on)
</script>
</body>
</html>
使用 JavaScript 模擬訂閱發(fā)布
function EventElement2 () {
this.subs = {}
}
EventElement2.prototype.$on = function(event, fn) {
// 如果有值就直接賦值,如果為空賦值 []
this.subs[event] = this.subs[event] || []
// 存儲(chǔ)事件
this.subs[event].push(fn)
}
EventElement2.prototype.$emit = function(event, params) {
// 判斷事件是否存在舱卡,存在去執(zhí)行相應(yīng)的事件
if (this.subs[event]) {
this.subs[event].forEach((fn) => {
fn(params)
})
}
}
let em2 = new EventElement2
em2.$on('click', (val) => {
console.log('click2 ---->', val)
})
em2.$emit('click', 'hello')
使用 ES6 的方式實(shí)現(xiàn)
// 事件觸發(fā)器
class EventElement {
constructor() {
// this.subs = {}
this.subs = Object.create(null) // 這樣寫性能會(huì)好一點(diǎn)
}
// 注冊(cè)事件
$on(event, fn) {
// 如果有值就直接賦值闽颇,如果為空賦值 []
this.subs[event] = this.subs[event] || []
// 存儲(chǔ)事件
this.subs[event].push(fn)
}
// 觸發(fā)事件
$emit(event, params) {
// 判斷時(shí)間是否存在毁腿,存在去執(zhí)行相應(yīng)的事件
if (this.subs[event]) {
this.subs[event].forEach((fn) => {
fn(params)
})
}
}
}
let em = new EventElement
em.$on('click', (val) => {
console.log('click1 ---->', val)
})
em.$emit('click', 'hello')
觀察者模式和訂閱發(fā)布模式的區(qū)別
觀察者模式是由具體的目標(biāo)調(diào)用汰蜘,例如:當(dāng)事件觸發(fā) Dep 就會(huì)去調(diào)用觀察者的方法仇冯,所以訂閱者和觀察者之間是存在依賴的。 觀察者模式
發(fā)布訂閱模式是由統(tǒng)一的調(diào)度中心調(diào)用族操,因?yàn)榘l(fā)布者和訂閱者不需要知道對(duì)方的存在。