Emit and handle events

Author: Dawid Adach

-

Currently, our Event component displays an icon that is supposed to delete the item from the list. As you already know, the list of the Events is held in the parent component - App. Therefore, it's not possible for the Event component to delete itself.

In order to delete an event from a list, we have to pass a call from the child component (Event) to its parent component (App). In this lesson, we will learn how to pass function calls between components.

Before we start to that, let's work on App template first:

1. App template

1.1. Style

We don't need styles anymore, so let's remove them from both of the App.vue and Event.vue files.

1.2. Template

Let's update the template of our app:


<template>
  <mdb-container>
    <mdb-row>
      <mdb-col col="9">
        <h2 class="text-uppercase my-3">Today:</h2>
        <Event
          v-for="(event, index) in events"
          :index="index"
          :time="event.time"
          :title="event.title"
          :location="event.location"
          :description="event.description"
          :key="index"
        />
        <mdb-row>
          <mdb-col xl="3" md="6" class="mx-auto text-center">
            <mdb-btn color="info">Add Event</mdb-btn>
          </mdb-col>
        </mdb-row>
      </mdb-col>
      <mdb-col col="3">
        <h3 class="text-uppercase my-3">Schedule</h3>
        <h6 class="my-3">
          It's going to be busy that today. You have
          <b>{{events.length}} events</b> today.
        </h6>
        <h1 class="my-3">
          <mdb-row>
            <mdb-col col="3" class="text-center">
              <mdb-icon far icon="sun"/>
            </mdb-col>
            <mdb-col col="9">Sunny</mdb-col>
          </mdb-row>
          <mdb-row>
            <mdb-col col="3" class="text-center">
              <mdb-icon icon="thermometer-three-quarters"/>
            </mdb-col>
            <mdb-col col="9">23°C</mdb-col>
          </mdb-row>
        </h1>
        <p>
          Don't forget your sunglasses. Today will dry and sunny, becoming
          warm in the afternoon with temperatures of between 20 and 25
          degrees.
        </p>
      </mdb-col>
    </mdb-row>
  </mdb-container>
</template>
  

1.3. Script

Finally, let's import some missing components like mdbButton and mdbIcon from the library:


import { mdbContainer, mdbRow, mdbCol, mdbIcon, mdbBtn, } from "mdbvue";
[...]
  components: {
    mdbContainer,
    mdbRow,
    mdbCol,
    Event,
    mdbIcon,
    mdbBtn,
  },
  

Preview:

App preview

Note:
In the right-hand column, we added an Event counter which tells us how many events are scheduled for today. In order to get this number we are simply counting elements within the array using {{events.length}} function.

2. Delete Event function

Now we can create a function which removes a particular Event from an array. It's a very simple function which accepts the id of the event which we want to delete, and remove it from the array[] using the splice() function:


    handleDelete(eventIndex) {
      this.events.splice(eventIndex, 1);
    }	
  
In Vue we define new functions inside the methods:{} within the export{...} function.


 export default {
  name: "App",
  components: {
	[...]
  },
  data() {
	[...]
  },
  methods: {
    handleDelete(eventIndex) {
      this.events.splice(eventIndex, 1);
    }
  }
};
  

Now when our function is ready, we can emit an event from the Event component.

3. Event emitting

Let's define an event handler for our Event component:


  methods: {
    onDelete() {
      this.$emit('delete', this.index);
    }
  }
  

This function will emit an event with two parameters:

  • name of the event - in our case delete
  • payload - in our case it will be the id of the corresponding Event

Now we have to trigger it whenever users click on the delete icon. Let's therefore update our existing: <mdb-badge> tag.


<mdb-badge tag="a" color="danger-color" class="ml-2 float-right">-</mdb-badge>
 	
	  

with a @click.native function call.


    <mdb-badge @click.native="onDelete" tag="a" color="danger-color" class="ml-2 float-right">-</mdb-badge>
  

Now whenever a user clicks on the delete icon, next to the Event title, it will emit a new delete event with the id of the clicked Event.

4. Catching & handling events

The last thing we have to do is to catch the emitted event in App.ve. In order to do that, let's update our Event invocation within App template:


<Event
  v-for="(event, index) in events"
  :index="index"
  :time="event.time"
  :title="event.title"
  :location="event.location"
  :description="event.description"
  :key="index"
  @delete="handleDelete"
/>
  

As you noticed, we have added a @delete handle and bound it to the handleDelete function which created in step 2.

Delete Events

Now, whenever we click on a delete icon:

  1. User clicks on the delete icon
  2. @click.native calls the onDelete() function
  3. onDelete() emits an event
  4. The App component catches it and triggers handleDelete()
  5. handleDelete() deletes the corresponding element from the array

Flow

Finally, Vue automatically notices that the data model has changed and re-renders the list of events.


Rate this lesson

Previous lesson Download Next lesson

Spread the word:
Do you need help? Use our support forum

About the author

Dawid Adach
For more than 5 years Dawid worked as an IT Consultant specializing in SOA/EAI/ESB in the banking domain. He gained experience working in countries like Netherlands, Belgium, Poland and India developing enterprise-class systems for the most prestigious companies. Since co-founding mdbootstrap.com & brandflow.net in 2016 he has been using and teaching technologies such as Angular, TypeScript, PHP, AJAX, Mongo, SQL, Hadoop Stack, Virtualization, Automation and many others...