Vue中的事件总线(EventBus):

实现任意组件间的通信的一种工具

  • 所谓事件总线,说白了就是一个中间人,相当于旧式的电话接线员,它可以帮助我们进行组任意组件间的通信(我们之前学过父给子传:props , 子给父传:$emit),在Vue当中,事件总线是一个所有组件都能看见的一个 ”人”(Vue.protype) ,并且它的身上存在 $on , $off , $emit等属性(Vue.protype).原理如下:
    image

$bus事件总线设置位置的原理:

image

要想实现任意组件间的通信

    1. 所有的vc(组件的实例对象都能看得见)
    • (1)可以写在 Vue.protype 身上,[main.js] (推荐)
    • (2)也可以写在 window身上 (一般不推荐)
    1. 2.要有 $on , $off , $emit 等……

原理的实现流程:(实现组件A给组件B传数据)

  • 我们首先在 main.js 中为Vue的实例对象vm的原型(protype)身上建立一个中间人(事件总线$bus),其次在组件A的身上,利用$emit(‘自定义事件’ , 数据)创建一个自定义事件并且绑定在事件总线($bus)身上,随后将数据一并发送给组件B,在组件B中利用$on(‘组件A当中创建的自定义事件’ , (数据)=>{对接受的数据进行处理})监听事件总线($bus)身上传过来的组件A刚刚创建的一个自定义事件,接收并处理出过来的数据

使用流程:

  1. 安装全局事件总线:(main.js)

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

    1. 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。
      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        // 监听,接收和处理 xxx 传过来的数据
        this.$bus.$on('xxxx',this.demo)
      }
    2. 组件B提供数据:this.$bus.$emit('xxxx',数据)
    3. 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。

代码解析:

  • 1.main.js中的代码
    //引入Vue
    import Vue from 'vue'
    //引入App
    import App from './App.vue'
    //关闭Vue的生产提示
    Vue.config.productionTip = false

    //创建vm
    new Vue({
        el:'#app',
        render: h => h(App),

        // 在创建vm实例对象之前安装全局事件总线
        beforeCreate() {
            Vue.prototype.$bus = this //安装全局事件总线
        },
    })
  • 2.Student组件中的代码(组件A 发送)
    <template>
        <div class="student">
            <h2>学生姓名:{{name}}</h2>
            <h2>学生性别:{{sex}}</h2>
            <!-- 这里给事件总线设置一个回调函数用于发送姓名 -->
            <button @click="sendStudentName">把学生名给School组件</button>
        </div>
    </template>

    <script>
        export default {
            name:'Student',
            data() {
                return {
                    name:'张三',
                    sex:'男',
                }
            },
            mounted() {
                // console.log('Student',this.x)
            },
            methods: {
                sendStudentName(){
                    // 给事件总线绑定回调,发送数据
                    this.$bus.$emit('hello',this.name)
                }
            },
        }
    </script>
  • 3.School组件当中的代码(组件B 接收)
    <template>
        <div class="school">
            <h2>学校名称:{{name}}</h2>
            <h2>学校地址:{{address}}</h2>
        </div>
    </template>

    <script>
        export default {
            name:'School',
            data() {
                return {
                    name:'五邑大学',
                    address:'广东江门',
                }
            },
            mounted() {
                // console.log('School',this)

                // 监听,接收和处理 hello 传过来的数据
                this.$bus.$on('hello',(data)=>{
                    // 对接收到的数据进行处理
                    console.log('我是School组件,收到了Student的数据',data)
                })
            },
            beforeDestroy() {
                // 解绑 hello 自定义事件,释放资源
                this.$bus.$off('hello')
            },
        }
    </script>

结果展示:

image