10、實現(xiàn)Vue組件之間的通信

父組件 → 子組件



組件實例的作用域都是孤立的,也就是子組件在模板 template 不能引用父組件的數(shù)據(jù),那么,當子組件有需要使用父組件的時候,我們該怎么辦呢?
這里我們使用的是組件的 props 選項來聲明它想要得到的數(shù)據(jù)。
首先創(chuàng)建一個 vue 實例:

<div id="app"></div>

<script>
const app = new Vue({
  el: '#app',
  data: {
    msg: '我是父組件的數(shù)據(jù)'
  }
})
</script>

實例 app 中含有數(shù)據(jù) msg 值為“我是父組件的數(shù)據(jù)”,待會我們把它傳遞給子組件。
子組件還沒有注冊,接下來,我們就注冊一個組件,組件名為 son。

<div id="app">
  <son></son>
</div>

Vue.component('son', {
  template: `<div></div>`
})

子組件準備好了,下一步就開始傳遞數(shù)據(jù),父組件向子組件傳遞參數(shù),我們說過,用組件提供的 props 選項,接下來,我們就把父組件的 msg 傳給 子組件,并展示在頁面上。
上面代碼稍加修改:

<div id="app">
  <son :message="msg"></son>
</div>
Vue.component('son', {
  props: ['message'],
  template: `<div>{{ message }}</div>`
})

效果如下:


效果圖.png

注意:props 是單向綁定的(父→子),是 vue 為了防止子組件無意修改了父組件得數(shù)據(jù)和狀態(tài),如果多個子組件任意地對父組件進行修改,這會讓整個應用得數(shù)據(jù)流難以閱讀。

如果你想要修改父組件傳過來得數(shù)據(jù),最好是定義一個局部的變量,來依賴傳過來的數(shù)據(jù)。

子組件 → 父組件



相比父→子組件通信,子→父組件就稍微繁瑣一點,我們會使用到組件的一個知識點:自定義事件。

每一個 vue 實例都實現(xiàn)了事件接口,我們可以用它提供的 API $emit(eventName) 來觸發(fā)一個事件。

首先注冊一個新組件:

Vue.component('son', {
  template: `<button @click="send">
                點擊
             </button>`,
  methods: {
    send() {
      this.$emit('connect')
    }
  }
})

很簡單的一個組件,就是一個按鈕 button,點擊它的時候,會觸發(fā)組件內(nèi)部的 send() 方法,而方法里面會觸發(fā)一個事件,事件名取為:connect
然后我們就去父組件監(jiān)聽這個事件“connect”,監(jiān)聽方式跟普通原生的事件一模一樣,也是用 v-on 指令,縮寫用 @ 符號。我們采用縮寫來監(jiān)聽:

<div id="app">
  <son @connect="say"></son>
</div>

我們設置了事件 connect 觸發(fā)的處理程序是一個 say() 方法,我們補上 say() 方法的定義:

const app = new Vue({
  el: '#app',
  methods: {
    say() {
      console.log('大家好,我監(jiān)聽到了事件connect的觸發(fā)')
    }
  }
})

我們在 say() 方法觸發(fā)的時候,在控制臺打印一句話,表示我們自定義的事件 connect() 成功觸發(fā),并被父組件監(jiān)聽到了。
效果如下:


效果圖.png

接下來就是把子組件的數(shù)據(jù)傳遞給父組件。

Vue.component('son', {
  template: `<button @click="send">點擊</button>`,
  data() {
    return {
      msg: '大家好,我是子組件的數(shù)據(jù)'
    }
  },
  methods: {
    send() {
      this.$emit('connect', this.msg)
    }
  }
})

我們把子組件的 data 中的 msg,通過 $emit() 一并發(fā)射出來,在父組件的 say() 方法接受即可。

methods: {
  say(msg) {
    console.log(msg)
  }
}

效果如下:


效果圖.png

非父子組件通信



除了父子組件的相互通信,非父子關系的組件該如何通信,我們可以巧妙 地利用一個空的 vue 實例來作為一個中央事件總線。
但是在事件開發(fā)中,我們不會這么做,我們會使用專門用于狀態(tài)管理的 vuex,vuex 的學習我們在后面學習。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。