vue組件通信---非父子組件(bus)/任意組件間的通信(pubsub)

方式一:bus中央總線

利用總線方式可以平級組件進行通信

無論是父向子傳值還是子向父傳值,都需要一箇中間介質。對於平級組件來說其實也一樣,他們也需要一箇中間介質來作爲一箇中央事件總線。

第一步:我們先來創建中央事件總線,在src/assets/下創建一個eventBus.js,內容如下

import Vue from 'vue'

export default new Vue();

eventBus.js中我們只創建了一個新的Vue實例,以後它就承擔起了組件之間通信的橋樑了,也就是中央事件總線。

第二步:創建一個firstChild組件,引入eventBus這個事件總線,接着添加一個按鈕並綁定一個點擊事件

firstChild.vue

<template>
    <div class="firstChild">
        <h2>子1</h2>
        <button @click="sendMsg">向兄弟2中傳值</button>
    </div>
</template>
<script>
import bus from './bus';//引入中央總線Vue實例
export default {
    data() {
        return {
            msg: '向兄弟2中傳值'
        }
    },
    methods: {
        sendMsg() {
            /** 
             * $emit()觸發事件並傳值
            */
            bus.$emit('userDefindEvent', this.msg)
        }
    }
}
</script>

我們在響應點擊事件的sendMsg函數中用$emit觸發了一個自定義的userDefinedEvent事件,並傳遞了一個字符串參數
PS:$emit實例方法觸發當前實例(這裏的當前實例就是bus)上的事件,附加參數都會傳給監聽器回調。

第三步:我們再創建一個secondChild組件,引入eventBus事件總線,並用一個p標籤來顯示傳遞過來的值

secondChild.vue

<template>
    <div class="secondChild">
        <h2>子2</h2>
        <p>從firstChild接收的字符串參數:{{msg}}</p>
    </div>
</template>
<script>
import bus from './bus';
export default {
    data() {
        return {
            msg: '默認值'
        }
    },
    mounted() {
        let _this = this 
        //定義監聽事件
        bus.$on('userDefindEvent',function(msg) {
            _this.msg = msg
        })
    }
}
</script>

我們在mounted中,監聽了userDefinedEvent,並把傳遞過來的字符串參數傳遞給了$on監聽器的回調函數
PS:
mounted:是一個Vue生命週期中的鉤子函數,簡單點說就類似於jquery的ready,Vue會在文檔加載完畢後調用mounted函數。
$on:監聽當前實例上的自定義事件(此處當前實例爲bus)。事件可以由$emit觸發,回調函數會接收所有傳入事件觸發函數($emit)的額外參數。

第四步:創建一個parent父組件,在父組件中,註冊這兩個組件,並添加這兩個組件的標籤

parent.vue

<template>
    <div class="parent">
        <h1>中央總線通信</h1>
        <first-child></first-child>
        <second-child></second-child>
    </div>
</template>
<script>
import firstChild from './firstChild';
import secondChild from './secondChild'
export default {
    data() {
        return {

        }
    },
    components: {
        firstChild,secondChild
    }
}
</script>

總結:

  • 創建一個事件總線,例如demo中的eventBus,用它作爲通信橋樑
  • 在需要傳值的組件中用bus.$emit觸發一個自定義事件,並傳遞參數
  • 在需要接收數據的組件中用bus.$on監聽自定義事件,並在回調函數中處理傳遞過來的參數

方式二:消息訂閱與發佈(PubSubJS 庫)

pubsub的優點:組件之間的通信沒有任何位置的限制

首先安裝pubsub-js庫

    npm install pubsub-js --sava

pubsub有兩個方法:

    PubSub.publish('發佈的消息名','提供給訂閱者的參數')             //發佈消息  ==>觸發事件 比如點擊事件

舉例:PubSub.subscribe('infomation_1',data)

    PubSub.subscribe('發佈的消息名',事件的監聽函數)                //訂閱消息   ==>綁定事件監聽 獲取消息

舉例:PubSub.subscribe('infomation_1',function(msg,data){

    })

案例:

父組件parent.vue

<template>
    <div class="parent">
        <h1>消息訂閱與發佈PubSub</h1>
        <first-child></first-child>
        <second-child></second-child>
    </div>
</template>
<script>
import firstChild from './firstChild'
import secondChild from './secondChild'
export default {
    data() {
        return {

        }
    },
    components: {
        firstChild,secondChild
    }
}
</script>

子組件firstChild.vue ---發佈消息

<template>
    <div class="firshChild">
        <h2>子1</h2>
        <button @click="sendMsg">向secondChild中傳值</button>
    </div>
</template>
<script>
// 引入pubsub-js插件
import PubSub from 'pubsub-js'
export default {
    data() {
        return {
            msg: 'muzidigbig'
        }
    },
    methods: {
        sendMsg() {
            PubSub.publish('userEvent',this.msg); //發佈消息
        }
    }
}
</script>

子組件secondChild.vue ---訂閱消息

<template>
    <div class="secondChild">
        <h2>子2</h2>
        <p>firshChild傳過來的數據:{{msgg}}</p>
    </div>
</template>
<script>
import PubSub from 'pubsub-js'
export default {
    data() {
        return {
            msgg: ''
        }
    },
    mounted() {
        // 訂閱消息
        PubSub.subscribe('userEvent',(msg,data) => {
            this.msgg = data
        })
    }
}
</script>

 注意
1) 優點: 此方式可實現任意關係組件間通信(數據)

 

 

 

發佈了246 篇原創文章 · 獲贊 260 · 訪問量 36萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章