淺析vue中的元件通訊

bluesboneW發表於2018-05-09

為了方便展示,所有的元件都是以單檔案元件的方式編寫的

1. 父元件對子元件通訊

在父元件內使用v-on繫結自定義事件,在子元件內使用props傳遞自定義的事件名稱

如下是父元件

<template>
  <div id="app">
    <child :message="title"/>
    <!--使用v-on繫結自定義事件-->
  </div>
</template>

<script>
  import Child from `./components/Child` // 匯入子元件

  export default {
    name: `App`,
    components: {Child}, // 註冊子元件
    data() {
      return {
        title: `父元件向我傳遞了資訊`
      }
    }
  }
</script>

如下是子元件

<template>
  <div id="app">
    {{message}}
  </div>
</template>

<script>
  export default {
    props: [`message`] // 使用props傳遞資料
  }
</script>

<!–more–>

2.子元件對父元件通訊

子元件對父元件通訊我們只能通過自定義事件去進行觸發,而無法像父對子通訊那樣直接進行資料傳遞

首先我們必須瞭解Vue暴露兩個例項方法

  • vm.$emit( event, […args] ),觸發當前例項上的事件,附加引數都會傳給監聽器回撥
  • vm.$on( event, callback ),監聽當前例項上的自定義事件,事件可以由vm.$emit觸發,回撥函式會接收所有傳入事件觸發函式的額外引數

總結一下:我們用$on去監聽一個**自定義事件**,這個自定義事件由$emit觸發,觸發的同時將data放在附加引數裡,傳給$on接收

如下是父元件

<template>
  <div id="app">
    <child v-on:receiveData="consoleData"/>
    <!--監聽自定義事件receiveData,監聽到之後觸發consoleData獲取子元件傳遞的資料-->
  </div>
</template>

<script>
  import Child from `./components/Child` // 匯入子元件

  export default {
    name: `App`,
    components: {Child}, // 註冊子元件
    methods: {
      consoleData(data) {
        // 這裡的引數是由$emit傳遞來的資料
        console.log(data) // ["子元件向我傳遞資訊啦", "測試"]
      }
    }
  }
</script>

如下是子元件

<template>
  <div id="app">
    <button @click="transData">點我,向父元件傳遞資料</button>
    <!--繫結transData事件,以便執行器內部的$emit-->
  </div>
</template>

<script>
  export default {
    data() {
      return {
        message: `子元件向我傳遞資訊啦`,
        title: `測試`
      }
    },
    methods: {
      transData() {
        // 觸發自定義事件receiveData,將資料傳遞給父元件
        this.$emit(`receiveData`, [this.message, this.title])
      }
    }
  }
</script>

3.兄弟元件之間進行通訊

主要我們通過全域性註冊一個eventBus單檔案元件,這個元件的作用充當著vm.$emit( event, […args] )裡的vm,其它形式與第二小節類似,不作過多說明了

新建一個js檔案,作為EventBus

import Vue from `vue` // 匯入vue模組

export default new Vue({}) // 新建一個空的vue例項作為EventBus

如下是父元件

<template>
  <div id="app">
    <!--兩個子元件-->
    <child1/>
    <child2/>
  </div>
</template>

<script>
  import Child1 from `./components/Child` // 匯入子元件1
  import Child2 from `./components/child2` // 匯入子元件2

  export default {
    name: `App`,
    components: {Child1, Child2}// 註冊兩個子元件
  }
</script>

如下是子元件1

<template>
  <div>
    <button @click="transData">點我,向兄弟元件Child2傳遞資料</button>
    <!--繫結transData事件,以便執行器內部的$emit-->
  </div>
</template>

<script>
  import eventBus from `./EventBus` // 匯入EventBus

  export default {
    data() {
      return {
        message: `Child2,你好呀`,
        title: `測試`
      }
    },
    methods: {
      transData() {
        // 通過EventBus觸發自定義事件receiveData,將資料傳遞給Child2元件
        eventBus.$emit(`receiveData`, [this.message, this.title])
      }
    }
  }
</script>

如下是子元件2

<template>
  <div>
    <h1>我的兄弟元件Child1向我傳遞了資訊:{{message}}</h1>
    <!--繫結transData事件,以便執行器內部的$emit-->
  </div>
</template>

<script>
  import eventBus from `./EventBus` // 匯入EventBus

  export default {
    data() {
      return {
        message: ``
      }
    },
    created() {
      eventBus.$on(`receiveData`, data => {
        // 注意這裡使用箭頭函式是因為需要將this繫結父級的context,否則this指向eventBus
        this.message = data
      })
    }
  }
</script>

相關文章