Vue wrapper example Vue wrapper example vue.js vue.js

Vue wrapper example


It behaves that way because of how v-model works. What you are a looking at is a 2-way binding. Where if the value of selected in v-model="selected" changes, the value will be pushed down to the component.

When vm.$emit('input', this.value) is called, it tells the parent to update whatever variable is listening to changes, in this case selected, which it turn gets pushed back to the component such that its value gets changed.

To make it simpler to understand, this is the sequence of events:

  1. select2's value changes
  2. the select2 value change triggers an event emission
  3. the parent receives the event and updates selected
  4. the component's value gets assigned to the new value of selected
  5. the watcher for the value gets triggered and updates select2 with the new value

Good question though.

Caveat: Doing this is understandably poor practice. It will break it sad ways when used with 1-way bindings.


After writing my previous answer, I realized I missed something important: contexts.

On line 5 in the jsfiddle, there is this line:

var vm = this, why?

This is because later on, when doing vm.$emit, this.$emit will not work; the context has been changed.

  .on('change', function () {      //this = select2 element      vm.value // == 1      this.value // == 2      vm.$emit("input", this.value);  })

The value on the emit event is not that of the component, but of the select2 element.

While the value has not yet been changed on the component, the new value has been broadcasted to the parent.


Notice how select2 component used in the template:

<select2 :options="options" v-model="selected">  <option disabled value="0">Select one</option></select2>

In Vue.js using v-model with components could be simplified to:

<your-component    :value="selected"    @input="value => { selected = value }"></your-component>

So every time you emit an event from your component the value gets changed at the parent component.

Source