全局事件總線
在寫組件的時候,我們都知道父傳遞子
也知道子傳遞給父
但是組件間嵌套復雜的時候我們應該怎么通信呢?
有的小伙伴會說適用vuex,的確是可以解決問題的
下面我們說一下全局事件總線
一種組件間通信的方式,適用於任意的組件間通信。
場景描述
a-test組件向b-test傳遞數據.
我們就需要使用全局事件總線。
全局事件總線非常簡單
通過this.$bus.$emit('事件名',數據)進行提供數據
通過this.$bus.$on('事件名',(data)=>{ })接受數據
通過接受數據方的組件中銷毀對應的事件
beforeDestroy() {
this.$bus.$off('hello')
},
全局事件總線第一步: main.js中注入
// demo就是 vueComponent
// 因為 Vue.extend({})的返回值就是 vueComponent
let Demo = Vue.extend({})
// d就是vueComponent的實例對象哈
let d = new Demo();
Vue.prototype.x=d
我們需要有一個副本或者說傀儡來進行存放[通知]
我們將它放在vueComponent這個實例上
感覺這樣寫有點麻煩,后面我們想辦法優化一下
第二步: a-test發送數據
<template>
<div class="flexflex">
<el-button @click="gievHander">將數據傳遞給b-test組件</el-button>
<h2 >我是a-test組件</h2>
</div>
</template>
<script>
export default {
methods:{
gievHander(){
this.x.$emit('hello',666)
}
},
}
</script>
第三步:b-test組件接受數據
<template>
<div class="btest">
<h2>我是b-test組件</h2>
<div>傳遞過來的數據 {{ getDaoData }}</div>
</div>
</template>
<script>
export default {
data(){
return {
getDaoData:''
}
},
mounted(){
this.x.$on('hello',(data)=>{
// hello是監聽的事件名稱,
console.log('監聽的事件數據',data )
this.getDaoData=data
})
},
}
</script>
將第一步進行優化
雖然上面這樣的寫法雖然是可以的。
但是不夠簡潔。我們需要將main.js優化一下
new Vue({
router,
render: (h) => h(App),
<!-- 添加下面這四行行代碼 -->
beforeCreate() {
// 生命周期中的this指向的是vue實例
//安裝全局事件總線;x最好改為$bus
Vue.prototype.x=this
}
}).$mount("#app");
第三步:持續優化
當這個組件銷毀的時候,我們應該將事件銷毀
<template>
<div class="btest">
<h2>我是b-test組件</h2>
<div>傳遞過來的數據 {{ getDaoData }}</div>
</div>
</template>
<script>
export default {
data(){
return {
getDaoData:''
}
},
mounted(){
this.x.$on('hello',(data)=>{
// hello是監聽的事件名稱,
console.log('監聽的事件數據',data )
this.getDaoData=data
})
},
beforeDestroy() {
//組件銷毀的時候,銷毀對應的事件
this.x.$off('hello')
//注意 this.x.$off()表示銷毀事件總線的所有事件
},
}
</script>

消息訂閱與發布
有的同學可能會問,處了使用剛剛提供的哪一種,還有其他方法嗎?
還真的有,只不過需要依賴第三方庫!
cnpm i pubsub-js 需要安裝一下這個庫
安裝后,需要引入一下。
訂閱: pubsub.publish(消息名,數據)
接受:pubsub.subscribe(消息名,(msgName,data)=>{})
銷毀: pubsub.unsubscribe('xx')
a-test發送數據
<template>
<div class="flexflex">
<el-button @click="gievHander">將數據傳遞給b-test組件</el-button>
<h2 >我是a-test組件</h2>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
methods:{
gievHander(){
pubsub.publish('dingyueming','發布消息啦')
}
},
}
</script>
b-test接受數據
<template>
<div class="btest">
<h2>我是b-test組件</h2>
<div>傳遞過來的數據=> {{ getDaoData }}</div>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
data(){
return {
getDaoData:'',
pubId:''
}
},
mounted(){
this.pubId=pubsub.subscribe('dingyueming',(msgName,data)=>{
// 第一個參數是訂閱的名稱 msgName
// 第二個參數是數據
this.getDaoData=data
})
},
// 組件銷毀的時候,取消訂閱
beforeDestroy() {
pubsub.unsubscribe(this.pubId)
},
}
</script>
