跨component
執行方法或傳遞資料
export default function Bus(vue) {
// 存放所有component的 method
this.handles = {
// event: [function, function,...]
}
// 存放所有component的 uid和 method
this.eventUidMap = {
// uid:{
// event:[function, function]
// }
}
this.$on = (event, callback, vm) => {
if (!this.handles[event]) this.handles[event] = []
if (callback instanceof Function) this.handles[event].push(callback)
if (vm instanceof vue) this.setEventUidMap(vm._uid, event, callback)
}
this.setEventUidMap = (uid, event, callback) => {
if (!this.eventUidMap[uid]) this.eventUidMap[uid] = {}
if (!this.eventUidMap[uid][event]) this.eventUidMap[uid][event] = []
this.eventUidMap[uid][event].push(callback)
}
this.$off = (event, callback) => {
if (!this.handles[event]) return
// delete object property
if (!callback) delete this.handles[event]
else if (callback instanceof Function) {
let len = this.handles[event].length
for (let i = 0; i < len; i++) {
let cb = this.handles[event][i]
// delete function
if (cb === callback) this.handles[event].splice(i, 1)
}
}
}
// 刪除component的 uid
this.$offByUid = uid => {
let eventObj = this.eventUidMap[uid] || {}
// 遍遞每一個event
Object.keys(eventObj).forEach(event => {
// 遍地每一個event的function
eventObj[event].forEach(cb => {
this.$off(event, cb)
})
// delete all event
// delete eventObj[event]
})
delete this.eventUidMap[uid]
}
this.$emit = (event, ...args) => {
// return的資料都丟來這
// 如果沒 return,則回傳undefined
let result = []
if (this.handles[event]) {
let len = this.handles[event].length
for (let i = 0; i < len; i++) {
result.push(this.handles[event][i](...args))
}
}
return result
}
return this
}
import Bus from '@/bus.js'
let eventBus = {
install(vue) {
let bus = new Bus(vue)
// 等同是Vue.prototype.$eventBus = ...
// 因為要做成唯讀
Object.defineProperties(Vue.prototype, {
$eventBus: {
get: () => bus
}
})
// 所有的component,都可以有mixin內的功能
Vue.mixin({
beforeDestroy() {
// this是VueComponent
this.$eventBus.$offByUid(this._uid)
}
})
}
}
// 預設把Vue傳進去
// 因為Vue.prototype.$eventBus了,VueComponent同時也有「$eventBus」
Vue.use(eventBus)
export default {
name: 'levelOne',
data() {
return {
list: ['html', 'css', 'javascript']
}
},
components: {
LevelTwo
},
methods: {
eventHandler(...arg) {
console.log(arg)
console.log(this.list)
},
getListHandler() {
return { list: this.list }
}
},
created() {
// 新增事件到event bus
this.$eventBus.$on('levelOneEvent', this.getListHandler, this)
this.$eventBus.$on('levelOneEvent', this.eventHandler, this)
}
}
export default {
name: 'levelTwo',
data() {
return {
list: []
}
},
methods: {
displayListHandler() {
this.$eventBus.$emit('levelOneEvent').forEach(item => {
// 沒有回傳值的,會是undefined
if (item) {
Object.keys(item).forEach(key => {
if (key === 'list') this.list = item[key]
})
}
})
}
}
}