10. 项目 [vuejs-08]:与组件层次结构无关的事件、组件生命周期
项目 [vuejs-08] 演示了如何通过事件实现组件之间的通信,即使这些组件在组件层次结构中没有直接关联。项目 [vuejs-08] 的树形结构如下:

10.1. 主脚本 [main.js]
脚本 [main.js] 与前面的示例中保持一致。
10.2. 脚本 [even-bus.js]
脚本 [event-bus.js] 是我们将用于发送和监听事件的工具:
import Vue from 'vue';
const eventBus = new Vue();
export default eventBus;
脚本 [event-bus] 仅用于创建 [Vue] 类的实例(第 1-2 行)并将其导出(第 3 行)。类 [Vue] 拥有两个用于处理事件的方法:
- [Vue].$emit(名称, 数据):用于触发名为 [nom] 且与数据 [donnée] 关联的事件;
- [Vue].$on(名称, 函数):用于拦截名为 [nom] 的事件,并由函数 [fn] 进行处理。 函数 [fn] 将接收由事件发布者关联的 [donnée] 数据作为参数;
这种事件管理机制与组件层次结构无关。 只需确保需要进行此类通信的组件使用 [Vue] 类的同一实例来发布/监听事件即可。在本示例中,我们将使用由前面的脚本 [event-bus.js] 定义的实例 [eventBus]。
10.3. 主视图 [App.vue]
主视图 [App] 的代码如下:
<template>
<div class="container">
<b-card>
<b-alert show variant="success" align="center">
<h4>[vuejs-08] : événements indépendants de la hiérarchie des composants, cycle de vie des composants</h4>
</b-alert>
<!-- 通过事件进行通信的三个组件 -->
<Component1 />
<Component3 />
<Component2 />
</b-card>
</div>
</template>
<script>
import Component1 from "./components/Component1";
import Component2 from "./components/Component2";
import Component3 from "./components/Component3";
export default {
name: "app",
// 组件
components: {
Component1,
Component2,
Component3
}
};
</script>
- 第 8-10 行:主视图 [App] 使用三个 [Component1, Component2, Component3] 组件,这些组件将通过事件进行通信。这三个组件在视图 [App] 中处于同一层级。此外,它们之间不存在层级关系;
10.4. 组件 [Component1]
组件 [Component1] 的代码如下:
<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>
import eventBus from "../event-bus.js"
export default {
name: "component1",
// 组件状态
data() {
return {
data: "",
showMsg: false
};
},
// 事件管理方法
methods: {
// 事件管理[someEvent]
doSomething(data) {
this.data = data;
this.showMsg = true;
}
},
// 组件生命周期管理
// 事件 [created] - 组件已创建
created() {
// 监听事件 [someEvent]
eventBus.$on("someEvent", this.doSomething);
}
};
</script>
注释
- 第 4-6 行:一个警报,用于显示第 18 行中的数据 [data]。该数据将由第 25 行中的事件处理程序 [doSomething] 初始化。 该处理程序在接收到事件 [someEvent](第 34 行)时被激活。 警报的显示取决于第19行属性[showMsg]的值。该属性同样由第25行的事件处理程序[doSomething]设置;
- 第 32 行:函数 [created] 是一个事件处理程序。它处理事件 [created],该事件在组件的生命周期中触发。还有其他事件,如 [beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, beforeDestroy, destroyed]。 当组件被创建时,会触发事件 [created];
- 第 12 行:导入类 [Vue] 的实例 [eventBus];
- 第 34 行:用于监听事件 [someEvent]。当该事件发生时,将调用第 25 行中的方法 [doSomething];
- 第25行:方法[doSomething]接收参数[data],该参数包含事件[someEvent]的触发方与该事件关联的数据;
- 第26-27行:修改组件状态,使第4-6行的警报显示接收到的数据;
10.5. 组件 [Component2]
组件 [Component2] 如下所示:
<template>
<div>
<b-button @click="createEvent">Créer un événement</b-button>
</div>
</template>
<!-- 脚本 -->
<script>
import eventBus from '../event-bus.js'
export default {
name: "component2",
// 事件管理方法
methods: {
createEvent() {
eventBus.$emit("someEvent", { x: 2, y: 4 })
}
}
};
</script>
注释
- 第 3 行:一个用于创建事件的按钮。当用户点击此按钮时,将调用第 13 行中的 [createEvent] 方法;
- 第 8 行:导入由脚本 [event-bus.js] 定义的实例 [eventBus];
- 第14行:使用该实例触发名为[someEvent]的事件,该事件与数据[{ x: 2, y: 4 }]相关联。 最终,当用户点击第3行的按钮时,将触发事件[someEvent]。回顾[Component1]的定义,该组件将拦截此事件;
10.6. 组件 [Component3]
该组件的代码如下:
<template>
<b-row>
<b-col>
<b-alert show
v-if="showMsg">Evénement [someEvent] intercepté par [Component3]. Valeur reçue={{data}}</b-alert>
</b-col>
</b-row>
</template>
<script>
import eventBus from "../event-bus.js"
export default {
name: "component3",
// 组件状态
data() {
return {
data: "",
showMsg: false
};
},
methods: {
// 事件管理 [someEvent]
doSomething(data) {
this.data = data;
this.showMsg = true;
}
},
// 组件生命周期管理
// 事件 [created] - 组件已创建
created() {
// 监听事件 [someEvent]
eventBus.$on("someEvent", this.doSomething);
}
};
</script>
[Component3] 是 [Component1] 的克隆。它的存在仅是为了说明一个事件可以被多个组件拦截。
10.7. 运行项目 [vuejs-08]


