Vue全局事件总线以及消息订阅与发布

Vue全局事件总线(GlobalEventBus)

简介

一种可以在任意组件间通信的方式,本质上就是一个对象,他必须满足以下条件:
1.所有组件对象都必须能看见他。
2.这个对象必须能够使用 $on $emit $off方法去绑定、触发和解绑事件。(因为 $on ,和 $off 和 $emit 这三个方法在Vue原型对象上,所以,我们的全局事件总线就要放在Vue的原型对象(vue.prototype)上,以确保每个组件都能访问得到)

简单理解,全局事件总线其实就是一个中间介质,组件间的相互通信借助于这个中间介质,通过这个中间转换介质,从而完成数据的传递与接收,实现组件间的相互通信。

实现

安装全局事件总线

new Vue({
  ......
  beforeCreate(){
      Vue.prototype.$bus = this  //安装全局事件总线,$bus就是当前应用,然后就可以使用了
      }......
  })

使用事件总线

1.发送(提供)数据方:比如A组件想要接收B组件传递过来的数据,则在B组件中给$bus触发自定义事件。

this.$bus.$emit('xxxx',数据)   //xxxx为触发的事件名

2.接收数据方:比如A组件想要接收B组件传递过来的数据,则在A组件中给$bus绑定自定义时间,事件的回调留在A组件自身

methods:{
  receive(data){....}
},
......
mounted(){
  this.$bus.$on('xxxx',this.demo)  //xxxx为B组件中触发的事件名
  //或this.$bus.$on('xxxx',(data)=>{....})    //data为传递过来的数据  注意为箭头函数形式,this的指向才是vm,若是正常函数形式,this指向为undefined
}

解绑事件

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

完整实例代码

在main.js中

//脚手架已安装vue,不用自己安装vue
import Vue from 'vue'  
//引入app组件,它是所有组件的父组件 
import App from './App.vue'  
// 关闭vue的生产提示
Vue.config.productionTip = false
// 创建vue实例对象——vm
new Vue({
  // 将App组件放入容器中
  render: h => h(App),
  beforeCreate(){
    Vue.prototype.$bus = this    //安装全局事件总线
  }
}).$mount('#app')

App.vue组件

<template>
  <div>
    <SchoolMes ref="hw"/>
    <Student/>
  </div>
</template>
<script>
import SchoolMes from './components/SchoolMes.vue'
import Student from './components/Student.vue';
export default {
  name: 'App',
  components: {
    SchoolMes,
    Student
}
</script>
<style>
</style>

Student.vue组件

<template>
    <div class="demo">
        姓名:{{name}}
        <br>
        性别:{{sex}}
        <br>
        <button @click="sendStudentName">发送</button>
    </div>
  </template>
  <script>
  export default {
    name: 'SchoolMes',
    props: {
      msg: String
    },
    data() {
      return {
        name:'张三',
        age:18,
      }
    },
    methods:{
        sendStudentName(){
            this.$bus.$emit('stuName',this.name)
        }
    }
  }
  </script>  
  <style scoped>
.demo{
    background-color: skyblue;
}
</style>

SchoolMes.vue组件

<template>
  <div class="demo">
    学校:{{ name}}
    <br>
    地址:{{ address }}
  </div>
</template>
<script>
export default {
  name: 'SchoolMes',
  mounted(){
    this.$bus.$on('stuName',(data)=>{
      console.log(data)
    })
  },
  // 销毁对应自定义事件
  beforeDestroy() {
    this.$bus.$off('stuName')
  },
  data() {
    return {
      name: 'abcdefghjk',
      address: 'beijing',
    }
  }
}
</script>
<style scoped>
.demo{
  background: aquamarine;
}
</style>

在这里插入图片描述

消息订阅与发布

1.订阅消息∶消息名
2.发布消息︰消息内容
消息订阅与发布的工作流程:
在这里插入图片描述
需要借助第三方库,推荐pubsub-js
使用步骤:
1.安装:npm i pubsub-js
2.引入:import pubsub from ‘pubsub-js’
3.接收数据(订阅者订阅)

    mounted() {
        // 订阅消息
        this.pubsubId =  pubsub.subscribe('xxxx',(msgName,data)=>{
            console.log(`有人发布了${msgName}消息,消息内容是:${data}`)
        })
    },

4.提供数据(发布者发布)

   sendStudentName() {
      // 发布事件
      pubsub.publish('xxxx',666)
  }

5.取消订阅

   beforeDestroy() {
       pubsub.unsubscribe(this.pubsubId)
   }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值