11-全局数据总线

1. 定义

全局事件总线是一种组件间的通信方式,适用于任意组件之间的通信。
事件总线是程序员在工作中的总结,不是新的 api。

思考:全局事件总线思路是这样的:能不能在找一个地方能够让所有的组件看到,第二个有用 $on, $emit $off 等方法。基于此思路,window 对象是 js 内置的全局对象,如果在 window 上面绑定方法或者属性其他地方都可以调用,也就是满足了被任何组件看到的要求,但是 window 没有$on, $emit $off方法,并且在 window 上面绑定这么多东西也不太好。所以另外一个思路是 vm 是 vue 的实例对象,可以被任意组件发现,vm 也拥有这些方法,所以就在 main.js入口文件去绑定 vm。这就是事件总线。

2. 安装全局事件总线

new Vue({
 ....
 beforeCreated(){
  Vue.property.$bus = this // 安装全局事件总线,$bus 就是当前事件总线的 vm
 } 
})

3. 使用全局事件总线

  1. 接收数据:A组件想接收数据,则在 A 组件中给 $bus绑定自定义事件,事件的回调留在 A 组件自身中。
methods(){
  demo(data){...}
}
....
mounted(){
  this.$bus.$on("xxxx", this.demo)
}
  1. 提供数据:this.$bus.$emit('xxxx', 数据)

4. 解绑事件

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

5. 代码和案例

现在有 App 父级组件,已经两个兄弟组件 Student 和 School。我们需要把 Student 组件里的 name 值传给 App 和 School。写法,在接收的组件 App 和 School 组件里先定义函数
发送端写法 Student组件写法

<template>
  <div id="student">
    <h2>学生名:{{name}}</h2>
    <h2>学生年龄:{{age}}</h2>
    <button @click="sendStudentName">点击把student名字传给school</button>
    <button @click="sendNameToApp">把名字传给app组件</button>
  </div>
</template>
....
    methods: {
        //把数据给Student组件
        sendStudentName(){
            this.$bus.$emit("getStudnetName2",this.name)
        },
        //把数据给App组件
        sendNameToApp(){
            this.$bus.$emit('getStudentName',this.name)
        }
    }

接收端 App组件写法

mounted(){
      this.$bus.$on('getStudentName',(data)=>{
        console.log("我是app组件,我收到了数据", data)
        this.msg = this.msg + data
      })
    },
    beforeDestroy(){
      this.$bus.$off("getStudentName")
    }

接收端School组件写法

 mounted(){
    //this.x即是组件实例对象vc上绑定了一个$on的事件,这个事件名为 hello,后面是回调函数
        this.$bus.$on('getStudnetName2',(data)=>{
            console.log('我是school组件,我收到了数据', data)
        })
    },
    beforeDestroy(){
        this.$bus.$off("getStudnetName2") //在组件销毁时候解绑 hello事件
    }

main.js 里安装数据总线写法

// 该文件是整个项目的入口文件

// 引入vue
import Vue from 'vue'
// 引入APP组件,APP组件是整个项目的父组件
import App from './App.vue'
//关闭vue生产提示
Vue.config.productionTip = false

// const Demo = Vue.extend() // Vue.extend() 创建一个 VueComponent
// const d = new Demo() // VueComponent 的实例对象,d是VueComponent的实例对象 vc。vc上面可以访问到 $on, $off
// Vue.prototype.x = d // 这个是用 vc去绑定事件总线

// 创建vue实例对象 -- vm
new Vue({
  render: h => h(App),
  beforeCreate(){
    Vue.prototype.$bus = this //安装事件总线,this 值得是 vm
  }
}).$mount('#app')
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容