Vue组件间的通信(全局事件总线和消息订阅与发布)

113 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情

全局事件总线(GlobalEventBus)

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

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

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

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

      //方式1:
      mounted() {
        this.$bus.$on('hello',(data)=>{
        	console.log('我是School组件,收到了数据',data)
        })
        }
        //方式2:
      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.$bus.$on('xxxx',this.demo)
        //xxxx事件被触发了就调用this.demo
      }
      
      beforeDestroy() {
        this.$bus.$off('xxxx')
      }
      
    2. 提供数据:B组件提供数据,则在B组件中用this.$bus.$emit('xxxx',数据)触发事件xxxx

methods: {
	sendStudentName(){//可通过<button @click="sendStudentName">把学生名给School组件</button>触发
		this.$bus.$emit('hello',this.name)
	}
}
  1. 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。

消息订阅与发布(pubsub)

sendStudentName(){ this.bus.bus.emit('hello',this.name) }

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

  2. 使用步骤:

    1. 安装pubsub:npm i pubsub-js

    2. 引入: import pubsub from 'pubsub-js'(接受和提供数据的二者都需引入)

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

      //方式1:
      mounted() {
        	this.pid = pubsub.subscribe('hello',(msgName,data)=>{
        		console.log(this)//若不写成箭头函数,this为undefined
        	    console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data)
        	})
        }
      //方式2:
      methods:{
        demo(msgName,data){
        	console.log("hello消息收到了",data,this)
        }
      }
      mounted() {
        this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
      }
      
    4. 提供数据:pubsub.publish('xxx',数据)

    5. 最好在接收数据方的beforeDestroy钩子中,用PubSub.unsubscribe(pid)取消订阅。

      beforeDestroy() {
      	pubsub.unsubscribe(this.pid)
      }
      

数据提供方:

<template>
	<div class="student">
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<button @click="sendStudentName">把学生名给School组件</button>
	</div>
</template>

<script>
	import pubsub from 'pubsub-js'
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男',
			}
		},
		methods: {
			sendStudentName(){
				pubsub.publish('hello',666)
			}
		},
	}
</script>

数据接收方:

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

<script>
	import pubsub from 'pubsub-js'
	export default {
		name:'School',
		data() {
			return {
				name:'清华大学',
				address:'北京',
			}
		},
		mounted() {
			this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
				console.log(this)
				console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data)
			})
		},
		beforeDestroy() {
			pubsub.unsubscribe(this.pubId)
		},
	}
</script>