vue -- 非父子組件傳值,事件總線(eventbus)的使用方式

歡迎訪問個人我的博客:http://www.xiaolongwu.cnvue

前言

先說一下什麼是事件總線,其實就是訂閱發佈者模式;git

好比有一個bus對象,這個對象上有兩個方法,一個是on(監聽,也就是訂閱),一個是emit(觸發,也就是發佈),咱們經過on方法去監聽某個事件,再用emit去觸發這個事件,同時調用on中的回調函數,這樣就完成了一次事件觸發;github

這是一種設計模式,和語言沒有關係;設計模式

若是不太瞭解什麼是訂閱發佈者模式,請移步看這篇文章JavaScript設計模式--觀察者模式(發佈者-訂閱者模式)函數

在實際開發中,每每最麻煩的就是各類組件之間的傳值問題;若是利用事件總線就會讓這件事情變得很簡單;學習

vue自帶事件總線的短板

咱們都知道在vue被實例化以後,他就具有了充當事件總線對象的能力,在他上面掛了兩個方法,是$emit和$on;this

而vue文檔說的很明白,$emit會觸發當前實例上的事件,附加參數都會傳給監聽器回調;spa

因爲在實際工做中,咱們都是以組件的形式開發,每一個組件就是一個實例;.net

因此利用vue自帶的總線能力有很大的侷限性,最多隻能從子組件觸發到父組件中,而不能在非父子組件之間傳值;prototype

因此這時,咱們就須要有一個全局的事件總線對象,讓咱們掛載監聽事件和觸發事件;

舉個例子,子組件向父組件傳值;父組件向子組件傳值很簡單,咱們這裏不說
// 子組件中
<template>
  <div>
    <span>{{child}}</span>
    <input type="button" value="點擊觸發" @click="send">
  </div>
</template>
<script>
  export default {
    data () {
      return {
        child: '我是子組件的數據'
      }
    },
    methods: {
      send () {
      // 若是傳多個值就用逗號隔開 a, b, c
        this.$emit('fromChild', this.child)
      }
    }
  }
</script>
// 父組件
<template>
  <div>
    <span>{{name}}</span>
    // 在父組件中監聽 fromChild事件
    <child @fromChild="onFromChild"></child>
  </div>
</template>
<script>
  import child from './child'
  export default {
    components: {
      child
    },
    data () {
      return {
        name: ''
      }
    },
    methods: {
      onFromChild: function (data) {
        // data就是子組件傳過來的值
        // 若是傳過來多個值就用逗號隔開去接收 data1, data2, data3
        this.name = data
      }
    }
  }
</script>

實現全局事件總線對象的幾種方式

方式一,也是我本身使用的方式(推薦使用,簡單)

大概思路是 :在main.js,也就是入口文件中,咱們在vue的原型上添加一個bus對象;

具體實現方式以下:

下面的組件A和組件B能夠是項目中任意兩個組件
//在mian.js中
Vue.prototype.bus = new Vue()  //這樣咱們就實現了全局的事件總線對象

//組件A中,監聽事件
this.bus.$on('updata', function(data) {
    console.log(data)  //data就是觸發updata事件帶過來的數據
})

//組件B中,觸發事件
this.bus.$emit('updata', data)  //data就是觸發updata事件要帶走的數據

方式二,稍微有點麻煩,但也很容易理解

大概的實現思路: 新建一個bus.js文件, 在這個文件裏實例化一下vue;而後在組件A和組件B中分別引入這個bus.js文件,將事件監聽和事件觸發都掛到bus.js這個實例上,這樣就能夠實現全局的監聽與觸發了

寫個例子
bus.js文件
// bus.js文件
import Vue from 'vue'
export default new Vue()
組件A
// 組件A ,監聽事件send
<template>
  <div>
    <span>{{name}}</span>
  </div>
</template>
<script>
  import Bus from './bus.js'
  export default {
    data () {
      return {
        name: ''
      }
    },
    created() {
      let _this = this
      // 用$on監聽事件並接受數據
      Bus.$on('send', (data) => {
        _this.name = data
        console.log(data)
      })
    },
    methods: {}
  }
</script>
組件B
// 組件B, 觸發事件send
<template>
  <div>
    <input type="button" value="點擊觸發" @click="onClick">
  </div>
</template>
<script>
  import Bus from './bus.js'
  export default {
    data () {
      return {
        elValue: '我是B組件數據'
      }
    },
    methods: {
        // 發送數據
      onClick() {
        Bus.$emit('send', this.elValue)
      }
    }
  }
</script>

這樣咱們就完成了一個簡單非父子組件之間的傳值。

個人我的博客地址:http://www.xiaolongwu.cn

github資源地址:vue -- 非父子組件傳值,事件總線(eventbus)的使用方式

個人CSDN博客地址:https://blog.csdn.net/wxl1555

若是您對個人博客內容有疑惑或質疑的地方,請在下方評論區留言,或郵件給我,共同窗習進步。

郵箱:wuxiaolong802@163.com

相關文章
相關標籤/搜索