9. project [vuejs-07]: event propagation in the component hierarchy
The project directory structure is as follows:

9.1. The main script [main.js]
The main script [main.js] remains unchanged.
9.2. The main component [App]
The code for the [App] component is as follows:
<template>
<div class="container">
<b-card>
<b-alert show variant="success" align="center">
<h4>[vuejs-07]: Event propagation in the component hierarchy</h4>
</b-alert>
<Component1 />
</b-card>
</div>
</template>
<script>
import Component1 from './components/Component1'
export default {
name: "app",
components: {
Component1
}
};
</script>
The [App] component uses a new [Component1] component (lines 7, 13, 17).
9.3. The [Component11] component
The code for the [Component11] component is as follows:
<template>
<b-button @click="createEvent">Create an event</b-button>
</template>
<!-- script -->
<script>
export default {
name: "component11",
// component methods
methods: {
// Handle the [click] event on the button
createEvent() {
// emit an event with data
this.$emit("someEvent", { x: 2, y: 4 })
}
}
};
</script>
Comments
- lines 1–3: the [Component11] component contains only a button that can be clicked. When clicked, the [createEvent] method in lines 11–14 is executed;
- line 13: each [View] instance has a [$emit] method that allows an event to be emitted:
- the first parameter is the name of the emitted event;
- the second parameter is the data to be associated with this event;
- the emitted event travels up the hierarchy of components that contain the [Component11] component. It travels up the hierarchy until it finds a component capable of handling it. This process begins with the parent component of [Component11];
9.4. The [Component1] component
The code for the [Component1] component is as follows:
<template>
<b-row>
<!-- the component that triggers the event -->
<b-col cols="2">
<Component11 @someEvent="doSomething" />
</b-col>
<!-- message displayed by the event handler -->
<b-col>
<b-alert show
variant="warning"
v-if="showMsg">Event [someEvent] intercepted by [Component1]. Received value={{data}}</b-alert>
</b-col>
</b-row>
</template>
<script>
import Component11 from "./Component11";
export default {
name: "component1",
// components
components: {
Component11
},
// component state
data() {
return {
data: "",
showMsg: false
};
},
// event handling methods
methods: {
doSomething(data) {
// data is the object associated with the [someEvent] event
this.data = data;
// displays the alert
this.showMsg = true;
}
}
};
</script>
Visual rendering


Comments
- line 5: [Component1] is the parent of [Component11] and can therefore “listen” (that’s the term) for events emitted by this component. We know that [Component11] can emit the [someEvent] event. The attribute [@someEvent="doSomething"] indicates that if the [someEvent] event emitted by [Component11] occurs, then the [doSomething] method on line 33 must be executed;
- lines 9–11: a message displayed by the [doSomething] method. Its display is controlled by the Boolean [showMsg] on line 28. The alert displays the [data] attribute from line 27;
- Line 33: The [doSomething] method, executed when the [someEvent] event occurs (line 5), receives the [data] associated with this event as a parameter. This parameter is assigned to the [data] attribute on line 27, which is displayed by line 11;
- line 37: we set the [showMsg] attribute to [true] to display the alert from lines 9–11;
9.5. Running the project
