全局事件总线

一种组件间通信方式,适用于任意组件间通信。

规范写法

安装全局事件总线:

  1. new Vue({
  2. // .......
  3. beforeCreate() {
  4. Vue.prototype.$bus = this // 安装全局事件总线,$bus就是当前应用的vm
  5. },
  6. // .....
  7. })

使用事件总线:

接收数据:

  1. mounted() {
  2. // 为$bus绑定studentNameEvent事件
  3. this.$bus.$on('studentNameEvent', (studentName) => {
  4. this.studentName = studentName
  5. });
  6. }

发送数据:

  1. methods: {
  2. sendStudentName() {
  3. this.$bus.$emit('studentNameEvent', this.name)
  4. }
  5. }

最好在beforeDestroy钩子中,使用$off解绑当前组件所用到的事件。

其他写法

如果要满足任意组件间通信,需要所有组件都能拿到该对象。所以该对象可以有以下几种方式:

  1. 绑定在window对象上:window.$bus = xxxxx
  2. 绑定在VueComponent原型上。因为VueComponent原型是在源码中每次都新生成一份,所以需要修改源码
  3. 绑定在Vue原型上。因为VueComponent.prototype.__proto__ === Vue.prototype,所以组件调用时,如果自身、自身原型都找不到这个对象,就会去Vue原型上查找。Vue.prototype.$bus = xxxx

极不推荐方式2修改源码。推荐使用方式3绑定在Vue原型上

该总线对象需要有$on$emit$once等相关方法,这些方法在Vue原型上,所以需要总线对象是Vue实例或者VueComponent组件实例。

如果要将总线对象定义为组件实例对象,写法为:

  1. const BusVCClass = Vue.extend({}); // 通过Vue.extend创建一个组件的类对象
  2. const busVC = new BusVCClass(); // 实例化出一个组件对象
  3. Vue.prototype.$bus = busVC // 将Vue原型上的$bus设置成组件实例对象

如果要将对象设置成Vue实例对象,则需要利用Vue的beforeCreate钩子函数:

  1. new Vue({
  2. // .....
  3. beforeCreate() {
  4. Vue.prototype.$bus = this
  5. }
  6. // .....
  7. })

以上两种方式都可以正常使用,推荐使用方式2规范写法。

其他

自定义事件被触发时,在Vue的浏览器插件中切换到事件页面,可以看到触发的事件。