Skip to content

11. 项目 [vuejs-09]:使用插件 [eventBus]

项目 [vuejs-09] 与项目 [vuejs-08] 完全相同,只是引入了插件的概念。该项目的目录结构如下:

Image

11.1. 插件 [./plugins/event-bus]

脚本 [./event-bus.js] 与前例中的内容保持一致:


import Vue from 'vue';
const eventBus = new Vue();
export default eventBus;

插件 [./plugins/event-bus.js] 如下所示:


export default {
  install(Vue, eventBus) {
    // 向 Vue 类添加属性 [$eventBus]
    Object.defineProperty(Vue.prototype, '$eventBus', {
      // 当引用 Vue.$eventBus 时,返回第二个参数 [eventBus]
      get: () => eventBus,
    })
  }
}

注释

  • 插件 [Vue] 是一个具有函数 [install] 的对象(第 2 行)。当代码声明使用该插件时,该函数将被自动调用;
  • 第 1-9 行:脚本导出的对象;
  • 第 2 行:函数 [install] 在此处接受两个参数:
    • [Vue]:由指令 [import Vue from ‘Vue’] 生成的函数。可视为一个类;
    • [eventBus]:由脚本 [./event-bus] 导出的对象;
  • 第4-7行:通过添加属性[$eventBus],修改了函数[Vue]的定义(即原型)。 以 [classe] 为例,属性 [$eventBus] 被添加到类 [Vue] 中。因此,作为 [Vue] 实例的组件将能够访问该新属性;
  • 第 6 行表明,当引用属性 [Vue].$eventBus 时,将获取第 2 行中的参数 [eventBus]。 稍后我们将看到,该第二个参数将是脚本 [./event-bus.js] 导出的对象 [eventBus]。 因此,最终当 C 组件使用表达式 [C.$eventBus] 时,它将引用由脚本 [./event-bus.js] 导出的对象 [eventBus]。 这样可以避免它导入脚本 [./event-bus.js]。插件的优势就在于此:简化对由脚本 [./event-bus.js] 导出的对象 [eventBus] 的访问;
  • 需要注意的是,该插件本身不必命名为 [event-bus.js]。例如,也可以将其命名为 [plugin-event-bus]
  • 还需注意,[$eventBus]中的$符号是一种约定,用于标识通过插件添加的[Vue]的属性。我们不必遵循这一约定。但在本文中,我们将遵循该约定;

11.2. 主脚本 [main.js]

脚本 [./plugins/event-bus.js] 为框架 [Vue.js] 定义了一个插件。该插件目前尚未被使用,仅处于定义状态。由脚本 [main.js] 负责激活它:


// 导入
import Vue from 'vue'
import App from './App.vue'

// 插件
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue);

// bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

// eventbus
import eventBus from './event-bus';
import PluginEventBus from './plugins/event-bus';
Vue.use(PluginEventBus, eventBus);

// 配置
Vue.config.productionTip = false

// 项目实例化[App]
new Vue({
  render: h => h(App),
}).$mount('#app')

注释

  • 第 14-16 行用于激活插件 [PluginEventBus]。 在第16行之后,[Vue]类(函数)的所有实例都拥有[$eventBus]属性,该属性指向由脚本[./event-bus.js]导出的同一对象。项目中的每个组件都是如此;

11.3. 主视图 [App]

主视图 [App] 与上一个项目中的保持一致。

11.4. 组件 [Component1]

组件 [Component1] 现在使用其属性 [$eventBus] 来监听事件 [someEvent]


<template>
  <b-row>
    <b-col>
      <b-alert show
               variant="warning"
               v-if="showMsg">Evénement [someEvent] intercepté par [Component1]. Valeur reçue={{data}}</b-alert>
    </b-col>
  </b-row>
</template>

<script>
  export default {
    name: "component1",
    // 组件状态
    data() {
      return {
        data: "",
        showMsg: false
      };
    },
    // 事件管理方法
    methods: {
      // 事件管理[someEvent]
      doSomething(data) {
        this.data = data;
        this.showMsg = true;
      }
    },
    // 组件生命周期管理
    // 事件 [created] - 组件已创建
    created() {
      // 监听事件 [someEvent]
      this.$eventBus.$on("someEvent", this.doSomething);
    }
  };
</script>

注释

  • 第 33 行,使用了组件的 [this.$eventBus] 属性。此外,请注意第 11 行的脚本不再导入 [./event-bus.js] 脚本;

11.5. 组件 [Component2]

组件 [Component2] 现使用其属性 [$eventBus] 来触发事件 [someEvent]


<template>
  <div>
    <b-button @click="createEvent">Créer un événement</b-button>
  </div>
</template>
<!-- 脚本 -->
<script>
  export default {
    name: "component2",
    // 事件处理方法
    methods: {
      createEvent() {
        this.$eventBus.$emit("someEvent", { x: 2, y: 4 })
      }
    }
  };
</script>

注释

  • 第 13 行,使用了该组件的 [this.$eventBus] 属性。此外,请注意第 7 行的脚本不再导入 [./event-bus.js] 脚本;

11.6. 组件 [Component3]

组件 [Component3][Component1] 具有相同的代码。它同样监听事件 [someEvent]

11.7. 项目运行

Image

结果与前一个项目相同。