1. // libs/event.js
  2. // eventBus
  3. // import { ArraySpliceOne } from './utils'
  4. function EventBus() {
  5. this._events = {}
  6. }
  7. EventBus.prototype.on = function (type, fn, ctx = this) {
  8. if (!this._events[type]) {
  9. this._events[type] = []
  10. }
  11. this._events[type].push([fn, ctx])
  12. }
  13. EventBus.prototype.once = function (type, fn, ctx = this) {
  14. function magic() {
  15. this.off(type, magic)
  16. fn.apply(ctx, arguments)
  17. }
  18. magic.fn = fn
  19. this.on(type, magic)
  20. }
  21. EventBus.prototype.off = function (type, fn) {
  22. let _events = this._events[type]
  23. if (!_events) {
  24. return
  25. }
  26. if (!fn) {
  27. this._events[type] = null
  28. return
  29. }
  30. let count = _events.length
  31. while (count--) {
  32. if (_events[count][0] === fn || (_events[count][0] && _events[count][0].fn === fn)) {
  33. // ArraySpliceOne(_events, count)
  34. _events.splice(count, 1)
  35. }
  36. }
  37. }
  38. EventBus.prototype.emit = function (type) {
  39. let events = this._events[type]
  40. if (!events) { return }
  41. let len = events.length
  42. let copyEvents = [...events]
  43. for (let i = 0; i < len; i++) {
  44. let event = copyEvents[i]
  45. let [fn, ctx] = event
  46. if (fn) {
  47. fn.apply(ctx, [].slice.call(arguments, 1))
  48. }
  49. }
  50. }
  51. EventBus.prototype.offAll = function () {
  52. this._events = {}
  53. }
  54. export default new EventBus()

使用

  1. // libs/index.js
  2. // 挂载到vue原型上,以方便使用。(当然也可以不在页面里面导入使用)
  3. import Vue from 'vue'
  4. import EventBus from './event'
  5. Vue.prototype.$EventBus = EventBus
  1. // main.js
  2. // main入口文件引入
  3. import './libs'
  1. // home/a.vue
  2. this.$EventBus.emit('optClick', obj)
  3. // about/b.vue
  4. mounted() {
  5. this.$EventBus.on('optClick', (data) => {
  6. this.optClick(data)
  7. })
  8. }
  9. methods: {
  10. optClick(){}
  11. },
  12. beforeDestroy() {
  13. this.$EventBus.off('optClick')
  14. },