Vue.js 에서 아래와 같이 이벤트 핸들러로 클로저 형태의 핸들러 함수를 넘겨주게 되면 의도된 대로 동작하지 않고, 그렇다고 특별한 에러도 없이 아무런 반응이 없어 문제가 있는것을 확인 할 수 있다.

JavaScript

Vue.component('BaseCheckbox', {
  name: 'BaseCheckBox',
  template: 
    `
    <button type="button">
      <slot></slot>
    </button>
    `
});
new Vue({
  el: "#app",
  methods: {
    closureHandler: function(msg) {
      return evt => { alert(msg) }
    }
  }
})

HTML

<div id="app">
  <label>
    <!-- It will not work -->
    <base-checkbox v-on:click.native="closureHandler('foobar')">
      Click me
    </base-checkbox>
  </label>
</div>

이에 대한 해결 방법을 연구하다 크게 두가지 해결법을 알아내어 기록해본다.

propscallback 넘겨주기

JavaScript

Vue.component('BaseCheckbox', {
  name: 'BaseCheckBox',
  template: 
      `
    <button type="button" v-on:click="onClick">
      <slot></slot>
    </button>
    `,
  props: ['callback'],
  methods: {
    onClick: function(evt) {
      this.callback(evt);
    }
  }
});
new Vue({
  el: "#app",
  methods: {
    closureHandler: function(msg) {
      return evt => { alert(msg) }
    }
  }
})

HTML

<div id="app">
  <label>
    <!-- Make it work -->
    <base-checkbox v-bind:callback="closureHandler('foobar')">
      Click me
    </base-checkbox>
  </label>
</div>

자식이 되는 컴포넌트에서 이벤트 바인딩을 하여 props로 받은 callback 함수를 호출하도록 하는 해결방법이다.

object handler 사용

JavaScript

Vue.component('BaseCheckbox', {
  name: 'BaseCheckBox',
  template: 
      `
    <button type="button" v-on:click="onClick">
      <slot></slot>
    </button>
    `,
  methods: {
    onClick: function(evt) {
      this.$emit('press', evt);
    }
  }
});
new Vue({
  el: "#app",
  methods: {
    closureHandler: function(msg) {
      return evt => { alert(msg) }
    }
  }
})

HTML

<div id="app">
  <label>
    <!-- Make it work 2 -->
    <base-checkbox v-on="{ press: closureHandler('foobar') }">
      Click me
    </base-checkbox>
  </label>
</div>

마찬가지로 자식 컴포넌트에서 이벤트 바인딩을 하고, this.$emit(...)을 이용하여 부모에서 특정 이벤트로 바인딩을 할 수 있도록 전달해주는 방법이다. click은 원래 native event로 존재하기 때문에 press라는 커스텀 이벤트를 발생시키도록 하였다.