當組件監聽到用戶的行爲,須要觸發一些界面交互的時候,實例與組件之間、組件相互之間就須要進行通訊了。Vue裏面有兩個api能夠幫助咱們輕鬆地完成這件事,它們是$on
和$emit
。javascript
先來看一下咱們最後要完成的效果吧。初始狀態:
html
點擊按鈕之後隱藏文字:
vue
<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
裏面初始化一個showBox
爲true
,執行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' })
源碼地址:https://github.com/levblanc/v...
視頻攻略:小的不才,爲求一讚,自制 本期視頻攻略 在此。