이벤트 핸들링

이벤트 청취


v-on 디렉티브를 사용, DOM 이벤트를 듣고 트리거 될 때 JavaScript 실행 가능

//HTML
<div id="example-1">
    <button v-on:click="counter += 1">Add 1</button>
    <p>버튼 클릭 횟수는 {{ counter }} 입니다.</p>
</div>

//JavaScript
var example1 = new Vue({
    el: '#example-1',
    data: {
        counter: 0
    }
});

메소드 이벤트 핸들러


많은 이벤트 핸들러의 로직은 복잡할 것이므로, Javascript를 v-on속성값으로 보관하는 것은 간단하지 않음. 이 때문에 v-on이 호출하고자 하는 메소드의 이름을 받는 이유이다

//HTML
<div id="example-2">
    <button v-on:click="greet">Greet</button>
</div>

//JavaScript
var example2 = new Vue({
    el: '#example-2',
    data: {
        name: 'Vue.js'
    },
    methods: {
        greet: function (event) {
            alert('Hello ' + this.name + '!' )
            if (event) {
                alert(event.target.tagName)
            }
        }
    }
})
example2.greet()

인라인 메소드 핸들러


//HTML
<div id="example-3">
    <button v-on:click="say('hi')">Say hi</button>
    <button v-on:click="say('what')">Say what</button>
</div>

//JavaScript
new Vue({
    el: '#example-3',
    methods: {
        say: function (message) {
            alert(message)
        }
    }
})

때로 인라인 명령문 핸들러에서 원본 DOM 이벤트에 엑세스 해야할 수도 있음
$event를 사용함

//HTML
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
    Submit
</button>

//JavaScript
methods: {
    warn: function (message, event) {
        if (event) event.preventDefault()
        alert(message)
    }
}

이벤트 수식어


이벤트 핸들러 내부에서 event.preventDevault() 또는 event.stopPropagation()를 호출하는 것은 매우 보편적인 일이다.
메소드 내에서 쉽게 이 작업을 할 수 있지만, DOM 이벤트 세부 사항을 처리하는 대신 데이터 로직에 대한 메소드만 사용할 수 있으면 더 좋을 것같다

고 문서에 써있는데 무슨말인지 잘 모르겠지만, 저걸 해결하기 위해 v-on 이벤트에 이벤트 수식어를 제공함 

- .stop
- .prevent
- .capture
- .self
- .once

<!-- 클릭 이벤트 전파가 중단됩니다 -->
<a v-on:click.stop="doThis"></a>
<!-- 제출 이벤트가 페이지를 다시 로드 하지 않습니다 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 수식어는 체이닝 가능합니다 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 단순히 수식어만 사용할 수 있습니다 -->
<form v-on:submit.prevent></form>
<!-- 이벤트 리스너를 추가할 때 캡처모드를 사용합니다 -->
<!-- 즉 내부 엘리먼트를 대상으로 한  이벤트가 해당 엘리먼트에서 처리되기 전에 처리됩니다. -->
<div v-on:click.capture="doThis">...</div>
<!-- event.target이 엘리먼트 자체인 경우에만 트리거를 처리합니다 -->
<!-- 자식 엘리먼트에서는 안됩니다 -->
<div v-on:click.self="doThat">...</div>
<!-- 클릭 이벤트는 최대 한번만 트리거 됩니다. -->
<a v-on:click.once="doThis"></a>

키 수식어


키보드 이벤트를 청취할 때 v-on에 키 수식어를 추가할 수 있음
키코드를 전부 기억하는 것은 어렵기 때문에 Vue는 일반적으로 사용되는 키의 별칭을 제공함

<!-- keyCode가 13일 때만 vm.submit()을 호출합니다 -->
<input v-on:keyup.13="submit">
<!-- 위와 같습니다 -->
<input v-on:keyup.enter="submit">
<!-- 약어 사용도 가능합니다 -->
<input @keyup.enter="submit">
  • .enter
  • .tab
  • .delete
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right
  • .ctrl
  • .alt
  • .shift
  • .meta (맥에서 commad, 윈도우는 윈도우키)
    마우스 수식어
  • .left
  • .right
  • .middle
    위에 없는 별칭을 만들고 싶으면 아래와 같이 하면 된다.
// v-on:keyup.f1 이 가능합니다
Vue.config.keyCodes.f1 = 112

HTML로 된 리스너를 사용하는 이유


HTML로 된 리스너를 사용하는 이유를 모른다면 왜 HTML에 JS요소를 넣어서 쓰냐 하고 이해하기 힘들 수 있다. 다음은 그 이유다

  1. HTML 템플릿을 간단히 하여 JavaScript 코드 내에서 핸들러 함수 구현을 찾는 것이 더 쉽다
  2. JavaScript에서 이벤트 리스너를 수동으로 연결할 필요가 없으므로 ViewModel 코드는 순수 로직과 DOM이 필요하지 않고, 이렇게 하면 테스트가 쉬워짐
  3. ViewModel이 파기되면 모든 이벤트 리스너가 자동으로 제거되어 이벤트 제거에 대한 걱정이 필요 없어집니다.


+ Recent posts