vue CLI_5、全局事件总线、消息的订阅与发布

1、全局事件总线(GlobalEventBus)

  1. 一种组件间通信的方式,适用于任意组件间通信

  2. 安装全局事件总线:

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

    1. 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.$bus.$on('xxxx',this.demo)
      }
      
    2. 提供数据:this.$bus.$emit('xxxx',数据)

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

image

src\components\School.vue

<template>
    <div class="school">
        <h3>学校名称:{{name}}</h3>
        <h3>地址:{{address}}</h3>
    </div>
    
</template>

<script>

    export default  {
        name:"School",
        data(){
            return{
                name:"家里蹲",
                address:"某国"
            }
        },
        methods:{
        },
        mounted(){
            this.$bus.$on("hello",(data)=>{console.log("我是school组件,我收到了数据了",data);});
        },
        beforeDestroy(){
            this.$bus.$off("hello");
        }
    };

</script>

<style scoped>
.school{
    background-color:skyblue;
    padding:5px;
    margin-top:30px;
}
</style>

src\components\Student.vue

<template>
    <div class="student">
        <h3>学生姓名:{{name}}</h3>
        <h3>年龄:{{age}}</h3>
        <button @click="sendStudentName">把学生名给school组件</button>

    </div>
    
</template>

<script>    

    export default  {
        name:"School",
        data(){
            return{
                name:"张三",
                age:18,
            }
        },
        methods:{
            sendStudentName(){
                this.$bus.$emit("hello",this.name);
            }
        }
    };

</script>

<style scoped>
.student{
    background-color:pink;
    padding:5px;
}
</style>

src\App.vue


<template>
<div class="app">

  <h2>{{msg}}:{{studentName}}</h2>
  <School />
  <Student />

</div>
    
</template>

<script>

    //引入School组件
    import Student from "./components/Student.vue";

    import School from "./components/School.vue";

    export default {
        name:"App",
        components:{ 
          Student,
          School        
        },
        data(){
            return{
              msg:"你好啊",
              studentName:""
            }
        },
        methods:{
        },
    }

</script>

<style scoped>
.app{
  background-color:gray;
  padding: 5px;
}
</style>
 

src\main.js

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

//引入Vue
import Vue from "vue";

//引入App
import App from "./App.vue";

//关闭Vue的生产提示
Vue.config.productionTip=false;

// //下面几行代码绑定x比较麻烦,可以直接用vm进行绑定
// const vueComponent=Vue.extend({});
// const vc=new vueComponent();
// Vue.prototype.$bus=vc;


//创建vm
new Vue({
    render: h=>h(App),
    //利用钩子进行绑定
    beforeCreate(){
        Vue.prototype.$bus=this;//安装全局事件总线
    }
}).$mount("#app");



2、消息订阅与发布(pubsub)

  1. 一种组件间通信的方式,适用于任意组件间通信
    用的较少。

  2. 使用步骤:

    1. 安装pubsub:npm i pubsub-js

    2. 引入: import pubsub from 'pubsub-js'

    3. 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
      }
      
    4. 提供数据:pubsub.publish('xxx',数据)

    5. 最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid)取消订阅。

修改上面全局事件总线的school的js代码即可

<script>

    import pubsub from 'pubsub-js';

    export default  {
        name:"School",
        data(){
            return{
                name:"家里蹲",
                address:"某国"
            }
        },
        methods:{
        },
        mounted(){
            this.pubId=pubsub.subscribe("hello",function(msgName,data){
                console.log("有人发布了hello消息,hello消息的回调被执行了",data);
            });
            
        },
        beforeDestroy(){
            //组件实例销毁的时候取消订阅
            pubsub.unsubscribe(this.pubId);
        }
    };

</script>

修改上面全局事件总线的student的js代码即可

<script>
    import pubsub from "pubsub-js";    

    export default  {
        name:"School",
        data(){
            return{
                name:"张三",
                age:18,
            }
        },
        methods:{
            sendStudentName(){
                pubsub.publish("hello",666);
            }
        }
    };

</script>
posted @ 2022-04-10 18:24  青仙  阅读(81)  评论(0编辑  收藏  举报