vue全局事件總線和消息訂閱詳細講解


全局事件總線

在寫組件的時候,我們都知道父傳遞子
也知道子傳遞給父
但是組件間嵌套復雜的時候我們應該怎么通信呢?
有的小伙伴會說適用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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM