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) {
    // ajoute une propriété [$eventBus] à la classe Vue
    Object.defineProperty(Vue.prototype, '$eventBus', {
      // lorsque Vue.$eventBus est référencé, on rend le 2ième paramètre [eventBus]
      get: () => eventBus,
    })
  }
}

评论

  • 一个 [Vue] 插件是一个带有 [install] 函数的对象(第 2 行)。当代码声明使用该插件时,该函数会被自动调用;
  • 第 1–9 行:脚本导出的对象;
  • 第 2 行:此处的 [install] 函数接受两个参数:
    • [Vue]:由 [import Vue from ‘Vue’] 语句获取的函数。可视为一个类;
    • [eventBus]:由 [./event-bus] 脚本导出的对象;
  • 第 4–7 行:通过向 [Vue] 函数添加 [$eventBus] 属性来修改其定义(即原型)。若以 [class] 的概念来理解,相当于向 [Vue] 类添加了 [$eventBus] 属性。因此,作为 [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] 脚本将其激活:


// imports
import Vue from 'vue'
import App from './App.vue'
 
// plugins
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);
 
// configuration
Vue.config.productionTip = false
 
// instanciation projet [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",
    // component status
    data() {
      return {
        data: "",
        showMsg: false
      };
    },
    // event management methods
    methods: {
      // evt management [someEvent]
      doSomething(data) {
        this.data = data;
        this.showMsg = true;
      }
    },
    // component lifecycle management
    // évt [created] - the component has been created
    created() {
      // listen to event [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 -->
<script>
  export default {
    name: "component2",
    // méthodes de gestion des évts
    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

我们得到了与上一个项目相同的结果。