Vue.js When should I use events ?


Example

The following picture illustrates how component communication should work. The picture comes from The Progressive Framework slides of Evan You (Developer of VueJS).

Component communication

Here is an example of how it works :

DEMO

HTML

<script type="x-template" id="message-box">
    <input type="text" v-model="msg" @keyup="$emit('new-message', msg)" />
</script>
 
<message-box :msg="message" @new-message="updateMessage"></message-box>
<div>You typed: {{message}}</div>

JS

var messageBox = {
  template: '#message-box',
  props: ['msg']
};
 
new Vue({
  el: 'body',
  data: {
    message: ''
  },
  methods: {
    updateMessage: function(msg) {
      this.message = msg;
    }
  },
  components: {
    'message-box': messageBox
  }
});

The example above can be improved !

The example above shows how the component communication works. But in case of a custom input component, to synchronize the parent variable with the value typed, we sould use v-model.

DEMO Vue1

DEMO Vue2

In Vue1, you should use .sync on the prop sent to the <message-box> component. This tells VueJS to synchronize the value in the child component with the parent's.

Remember: Every component instance has its own isolated scope.

HTML Vue1

<script type="x-template" id="message-box">
  <input v-model="value" />
</script>

<div id="app">
  <message-box :value.sync="message"></message-box>
  <div>You typed: {{message}}</div>
</div>

In Vue2, there is a special 'input' event you can $emit. Using this event allows you to put a v-model directly on the <message-box> component. The example will look as follow:

HTML Vue2

<script type="x-template" id="message-box">
  <input :value="value" @input="$emit('input', $event.target.value)" />
</script>

<div id="app">
  <message-box v-model="message"></message-box>
  <div>You typed: {{message}}</div>
</div>

JS Vue 1 & 2

var messageBox = {
  template: '#message-box',
  props: ['value']
};

new Vue({
  el: '#app',
  data: {
    message: ''
  },
  components: {
    'message-box': messageBox
  }
});

Notice how faster the input is updated.