Article

How to emit an event to a child component in Vue.js

Remco Hendriksen on Dec 1, 2020
component events props
Last updated: May 30, 2022

Vue.js applications are all about creating components. Making them interact with each other is where the fun begins. Using props and events is the way how to do this in Vue.js. A common question around this topic is how to make your child-components react to events.

TL;DR. You don't.

You don't fire events to your child-components. Instead, you change the prop on a child-component and then use a watcher in that child-component to fire some logic.

Events fire up, props are passed down

Before we start with this example, you have to understand the following concept:

  • When a component wants to let its parent know something has happened, it fires an event outside of itself
  • When the parent wants to let the child know that something has changed, it modifies the prop that is passed to the child component'

So you don't pass events to a child-component, you change the prop of a child. And then in your child-component you create a watcher for that props. This is the way to make a child-component react on things happening outside of it.

The child component

This is a really simple button-component which can do 2 things. It can emit an event with the name 'icon-clicked' and it can alert whatever it gets through its buttonText-prop.

<template>
  <div class="button">
    {{ buttonText }}
    <i @click="$emit('icon-clicked', $event.target.value)">?</i>
  </div>
</template>
<script>
export default {
  props: {
    buttonText: {
      type: String,
      default: 'Submit',
    }
  },
  watch: {
    buttonText() {
      this.alertMe();
    }
  },
  methods: {
    alertMe() {
      window.alert(this.buttonText);
    }
  }
}
</script>

The child-component can do two things:

  • Emit an event with the name icon-clicked
  • Show an alert with the content of the prop buttonText

The watch property makes the alertMe method fire when the buttonText has changed.

The parent component

<template>
  <div class="container">
    <div class="help-text" v-if="showHelpText">Show some help text</div>
    <btn-component @icon-clicked="toggleHelpText" :button-text="buttonText"/>
  </div>
</template>
<script>
import BtnComponent from '~/components/BtnComponent'
export default {
  components: {
    BtnComponent
  },
  data() {
    return {
      showHelpText: false,
      buttonText: 'Help me',
    }
  },
  methods: {
    toggleHelpText() {
      this.showHelpText = !this.showHelpText
      this.buttonText = this.showHelpText ? 'Close me' : 'Help me';
    }
  }
}
</script>

When the btn-component has fired the event icon-clicked, the toggleHelpText method is being executed. This method sets two variables:

  • The buttonText is set to 'Close me' or 'Help me'
  • The showHelpText toggles the help-text block

That's it

This is the way you interact between components. You can use this concept in many ways.

Here are some more examples on using events in Vue.

Leave a comment below if you have got any questions about this article.

Leave a comment

More articles