The $emit Function in Vue

Aug 8, 2019

Vue components have a $emit() function that allows you to pass custom events up the component tree.

Vue.component('my-component', {
  mounted: function() {
    // `$emit()` sends an event up the component tree. The parent
    // can listen for the 'notify' event using 'v-on:notify'
    this.$emit('notify');
  },
  template: '<div></div>'
});

const app = new Vue({
  data: () => ({ show: false }),
  // Vue evaluates the expression in 'v-on:notify' when it gets a 'notify'
  // event. 
  template: `
    <div>
      <my-component v-on:notify="show = true"></my-component>
      <div v-if="show">Notified</div>
    </div>
  `
});

All Vue instances have a $emit() function, including both top-level apps and individual components.

const app = new Vue({
  template: '<div></div>'
});

let called = 0;
app.$on('test-event', () => { ++called; });

app.$emit('test-event');
called; // 1

Why $emit()?

Generally, you use $emit() to notify the parent component that something changed. For example, suppose you have a component input-name that takes a prop called name. This component exposes an input form asking the user for their name, and an 'Update' button that updates the name.

The way to do this is for input-name to $emit() an event called 'update' when the user clicks the 'Update' button, with the new name.

Vue.component('input-name', {
  data: () => ({ name: 'World' }),
  // When you click the "Update" button, Vue will emit an event `update`
  // to the parent, with the current state of 'name'.
  template: `
    <div>
      <input type="text" v-model="name">
      <button v-on:click="$emit('update', name)">
        Update
      </button>
    </div>
  `
});

const app = new Vue({
  data: () => ({ name: 'World' }),
  // To listen to the 'update' event, you create the `input-name`
  // component with a `v-on:update` attribute. `$event` contains
  // the value of the 2nd parameter to `$emit()`.
  template: `
    <div>
      <div>
        <input-name v-on:update="setName($event)"></input-name>
      </div>
      <h1>Hello, {{name}}</h1>
    </div>
  `,
  methods: {
    // Define a method that Vue will call to handle the 'update' event.
    setName: function(v) {
      this.name = v;
    }
  }
});
app.$mount('#content');

More Vue Tutorials