1. 程式人生 > 其它 >vue之事件匯流排

vue之事件匯流排

1.事件匯流排介紹

在vue中跨越層級的兩個元件進行通訊,若使用props傳值和$emit觸發的方式會十分繁瑣,而事件匯流排的通訊方式更適合跨越層級的元件通訊。

2.事件匯流排原理

事件匯流排可以用一個物件來表示每一個事件 都有一個數組來記錄這個事件的監聽者

{
  "event1": [hander1, hander2],
  "event2": [hander1, hander2, hander3],
}

若給某個事件新增監聽者,就把處理函式新增到這個事件對應的陣列中去

若給某個事件取消監聽者,就從這個事件對應的陣列刪除這個處理函式

若要觸發某個事件,就讓這個事件對應的陣列存放的處理函式依次執行

用class模擬一個事件匯流排

// 事件匯流排
class Bus {
  constructor() {
    // 用來記錄事件和監聽該事件的陣列
    this.listeners = {};
  }
  // 新增指定事件的監聽者
  $on(eventName, handler) {
    this.listeners[eventName].add(handler);
  }
  // 取消監聽事件
  $off(eventName, handler) {
    this.listeners[eventName].delete(handler);
  }
  // 觸發事件
  $emit(eventName, ...args) {
    
this.listeners[eventName].forEach((fn) => fn(...args)); } }

3.事件匯流排的使用

在main.js中,引入事件匯流排

import Vue from 'vue';
import App from './App.vue';
import router from './router/index.js';
// 將事件匯流排作為Vue.prototype的屬性,方便每個元件中通過this.$bus獲取事件匯流排
Vue.prototype.$bus = new Vue({});

new Vue({
  el: '#app',
  render: (h) 
=> h(App), router, });

直接使用vue例項作為事件匯流排,是因為vue例項上本身就具有這三個方法($on、$emit、$off)

home.vue中觸發事件匯流排的事件

<template>
  <div>
    <button @click="handleClick">點選</button>
    <!-- 使用test-comp元件 -->
    <test-comp></test-comp>
  </div>
</template>

<script>
import testComp from './test-comp.vue';
export default {
  name: 'Home',
  components: {
    testComp,
  },
  methods: {
    handleClick(event) {
      // 觸發事件匯流排中的事件,並傳引數
      this.$bus.$emit('my-click', [1, 2]);
    },
  },
};
</script>

test-comp.vue中訂閱事件匯流排中的事件

<template>
  <div class="red"></div>
</template>

<script>
export default {
  mounted() {
    // 訂閱事件匯流排中的事件,並接受引數(要等home.vue的this.$bus.$emit執行後才能執行)
    this.$bus.$on('my-click', (msg) => {
      console.log('接受元件home傳來的引數msg: ', msg);
    });
  },
  methods: {},
};
</script>