Vue 2 | Part 8 組件通訊

當組件監聽到用戶的行爲,須要觸發一些界面交互的時候,實例與組件之間、組件相互之間就須要進行通訊了。Vue裏面有兩個api能夠幫助咱們輕鬆地完成這件事,它們是$on$emitjavascript

實例和組件(parent child)之間的通訊

先來看一下咱們最後要完成的效果吧。初始狀態:
final-1html

點擊按鈕之後隱藏文字:
final-2vue

初始代碼

<div id="app">
    <div class="boxWrapper">
        <div>I am your Big Box</div>
    </div>
    <toggle-btn></toggle-btn>
</div>
Vue.component('toggle-btn', {
    template: '<button class="btn btn-info">Toggle Box</button>'
})

var app = new Vue({
    el: '#app'
})

咱們把按鈕作成一個簡單的組件,那應該怎麼獲取按鈕監聽到的點擊事件,傳給big box呢?java

監聽按鈕組件上的自定義事件

用戶點擊的時候,是在toggle-btn這個組件上觸發了事件,因此咱們信號的源頭,確定是在它身上。Vue容許咱們監聽組件上的自定義事件,像這樣:git

<toggle-btn v-on:toggle-box="toggleBox"></toggle-btn>

這裏有幾點須要注意的:github

  • 自定義的事件,須要用中劃線分詞,在HTML和JS都是。用駝峯分詞是徹底沒有效果的。api

  • 雖然監聽的是組件的自定義事件,但後面觸發的這個toggleBox方法,是在Vue實例上的。併發

  • 這裏是監聽的是自定義的事件,真正的click事件,是在組件內部進行監聽(下面會解釋)。app

因此上面的這行HTML的意思,實際上是,當Vue實例監聽到組件上自定義的toggle-box事件被觸發,就會執行它的toggleBox方法。ide

組件發佈信號

被監聽的事件有了,這個組件到底要怎麼把信號發佈出來,讓Vue實例監聽到呢?咱們直接來看下面這段代碼。

在組件的內部監聽到用戶的click事件後,執行自身的方法,把信號發佈出去。

Vue.component('toggle-btn', {
    template: '\
        <button \
            class="btn btn-info" \
            v-on:click="emmitToggle">Toggle Box</button>\
    ',
    methods: {
        emmitToggle: function() {
            // 用戶點擊以後,發佈信號
            this.$emit('toggle-box')
        }
    }
})

完善事件觸發的方法

接收到信號之後,咱們但願能夠toggle文字的顯示,最直接的固然是在實例上的data裏面初始化一個showBoxtrue,執行toggleBox方法的時候對它進行操做。同時,big box裏面的文字經過v-show指令來控制是否顯示。

<div class="boxWrapper">
    <div v-show="showBox">I am your Big Box</div>
</div>
var app = new Vue({
    el: '#app',
    data: {
        showBox: true
    },
    methods: {
        toggleBox: function() {
            this.showBox = !this.showBox
        }
    }
})

完整的通訊流程

  • 組件監聽用戶行爲(咱們的例子裏是點擊)

  • 用戶點擊,觸發組件自身的方法併發布信號($emit):我這邊的toggle-box事件被觸發了

  • HTML中的v-on指令捕捉到這個信號,執行Vue實例下的toggleBox方法

  • showBox的值被修改,v-show對文字進行隱藏或顯示

組件之間的通訊

其實$emit方法是掛在Vue實例下,每個Vue實例都會有$emit$on方法。因此能夠直接把vue實例做爲一個event bus,在組件之間進行通訊。

這裏簡單地舉個例子。比方說,咱們但願點擊toggle按鈕之後,另一個組件能夠接收到這個信號。

toggle-btn基本不變,只是改成使用event bus的$emit方法。listener中也一樣使用event bus的$on對信號進行監聽。

<div id="app">
    <listener></listener>
    <toggle-btn></toggle-btn>
</div>
var bus = new Vue()

Vue.component('toggle-btn', {
    template: '\
        <button \
            class="btn btn-info" \
            v-on:click="emmitToggle">Toggle Box</button>\
    ',
    methods: {
        emmitToggle: function() {
            // 注意這裏使用的是bus,不是this
            bus.$emit('toggle-box')
        }
    }
})

Vue.component('listener', {
    template: '<h5>sibling component</h5>',
    mounted: function () {
        bus.$on('toggle-box', function () {
            alert('已經接收到toggle-box信號!')
        })
    }
})

var app = new Vue({
    el: '#app'
})

sibling-com

寫在最後

源碼地址:https://github.com/levblanc/v...

視頻攻略:小的不才,爲求一讚,自制 本期視頻攻略 在此。

相關文章
相關標籤/搜索