Skip to content

10. Project [vuejs-08]: Events independent of the component hierarchy, component lifecycle

The [vuejs-08] project demonstrates how components not directly linked in the component hierarchy can nevertheless communicate via events. The directory structure of the [vuejs-08] project is as follows:

Image

10.1. The main script [main.js]

The [main.js] script remains the same as in the previous examples.

10.2. The [even-bus.js] script

The [event-bus.js] script is the tool we will use to emit and listen for events:


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

The [event-bus] script simply creates an instance of the [Vue] class (lines 1–2) and exports it (line 3). The [Vue] class has two methods for handling events:

  • [Vue].$emit(name, data): allows you to emit an event named [name] associated with the data [data];
  • [Vue].$on(name, fn): allows you to intercept the event named [name] and have it processed by the function [fn]. The function [fn] will receive the data [data] associated with the event by its emitter as a parameter;

This event handling is not tied to the component hierarchy. Components that wish to communicate in this way simply need to use the same instance of the [View] class to emit/listen for events. In our example, we will use the [eventBus] instance defined by the previous [event-bus.js] script.

10.3. The main view [App.vue]

The code for the main view [App] is as follows:


<template>
  <div class="container">
    <b-card>
      <b-alert show variant="success" align="center">
        <h4>[vuejs-08]: Events Independent of the Component Hierarchy, Component Lifecycle</h4>
      </b-alert>
      <!-- the three components that communicate via events -->
      <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
    components: {
      Component1,
      Component2,
      Component3
    }
  };
</script>
  • lines 8–10: the main view [App] uses three components [Component1, Component2, Component3] that will communicate via events. The three components are on the same level within the [App] view. Furthermore, there will be no hierarchical relationship between them;

10.4. The [Component1] component

The code for the [Component1] component is as follows:


<template>
  <b-row>
    <b-col>
      <b-alert show
               variant="warning"
               v-if="showMsg">Event [someEvent] intercepted by [Component1]. Value received={{data}}</b-alert>
    </b-col>
  </b-row>
</template>

<script>
  import eventBus from "../event-bus.js"
  export default {
    name: "component1",
    // component state
    data() {
      return {
        data: "",
        showMsg: false
      };
    },
    // event handling methods
    methods: {
      // Handle the [someEvent] event
      doSomething(data) {
        this.data = data;
        this.showMsg = true;
      }
    },
    // component lifecycle management
    // event [created] - the component has been created
    created() {
      // Listen for the [someEvent] event
      eventBus.$on("someEvent", this.doSomething);
    }
  };
</script>

Comments

  • Lines 4–6: An alert that displays the data [data] from line 18. This data will be initialized by the event handler [doSomething] on line 25. This handler is triggered upon receipt of the [someEvent] event (line 34). The alert is displayed based on the value of the [showMsg] attribute on line 19. This attribute is also set by the [doSomething] event handler on line 25;
  • line 32: the [created] function is an event handler. It handles the [created] event, an event emitted during the component’s lifecycle. There are others [beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, beforeDestroy, destroyed]. The [created] event is emitted when the component has been created;
  • line 12: the [eventBus] instance of the [Vue] class is imported;
  • line 34: it is used to listen for the [someEvent] event. When this event occurs, the [doSomething] method on line 25 is called;
  • line 25: the [doSomething] method receives the data that the emitter of the [someEvent] event associated with the event as the [data] parameter;
  • lines 26–27: the component’s state is updated so that the alert in lines 4–6 displays the received data;

10.5. The [Component2] component

The [Component2] component is as follows:


<template>
  <div>
    <b-button @click="createEvent">Create an event</b-button>
  </div>
</template>
<!-- script -->
<script>
  import eventBus from '../event-bus.js'
  export default {
    name: "component2",
    // event handling methods
    methods: {
      createEvent() {
        eventBus.$emit("someEvent", { x: 2, y: 4 })
      }
    }
  };
</script>

Comments

  • line 3: a button to create an event. When the user clicks this button, the [createEvent] method on line 13 is called;
  • line 8: the [eventBus] instance defined by the [event-bus.js] script is imported;
  • line 14: this instance is used to emit an event named [someEvent] associated with the data [{ x: 2, y: 4 }]. Ultimately, when the user clicks the button on line 3, the [someEvent] event is emitted. If we recall the definition of [Component1], it will intercept this event;

10.6. The [Component3] component

The code for this component is as follows:


<template>
  <b-row>
    <b-col>
      <b-alert show
               v-if="showMsg">Event [someEvent] intercepted by [Component3]. Received value={{data}}</b-alert>
    </b-col>
  </b-row>
</template>

<script>
  import eventBus from "../event-bus.js"
  export default {
    name: "component3",
    // component state
    data() {
      return {
        data: "",
        showMsg: false
      };
    },
    methods: {
      // Handle the [someEvent] event
      doSomething(data) {
        this.data = data;
        this.showMsg = true;
      }
    },
    // component lifecycle management
    // event [created] - the component has been created
    created() {
      // Listen for the [someEvent] event
      eventBus.$on("someEvent", this.doSomething);
    }
  };
</script>

[Component3] is a clone of [Component1]. It is only there to demonstrate that an event can be intercepted by multiple components.

10.7. Running the [vuejs-08] project

Image

Image

Image