티스토리 뷰

Vue.JS

[Vue.JS] 이벤트 핸들링

버미노트 2018. 12. 6. 01:15

1. 이벤트 리스너

v-on 디렉티브는 이벤트 리스너입니다. v-on 디렉티브는 DOM 이벤트가 발행하는지 듣고 있다가 이벤트가 발생 했을 때 JavaScript를 실행합니다.

<div id="app">
  <button v-on:click="counter += 1">Add 1</button>
  <p>위 버튼을 클릭한 횟수는 {{ counter }} 번 입니다.</p>
</div>
new Vue({
  el: '#app',
  data: {
    counter: 0
  }
});

위의 예제는 v-on이라는 이벤트 리스너가 click 이벤트가 발행하는지 듣고 있다가 이벤트가 발생 되었을 때 간단한 JavaScript를 실행하는 예제입니다. CodePen에서 결과를 확인 할 수 있습니다.

2. 메소드 이벤트 핸들러

대부분의 이벤트 핸들러의 로직은 복잡하기 때문에 v-on에 JavaScript로 넘겨주기 어렵습니다. 그렇기 때문에 v-onmethods의 함수를 넘겨주는 형태로 구현 하는 것이 좋습니다.

<div id="app">
  <button v-on:click="greet">Greet</button>
</div>
new Vue({
  el: '#app',
  data: {
    name: 'Vue.js'
  },
  // 메소드는 `methods` 객체 안에 정의합니다
  methods: {
    greet: function (event) {
      // 메소드 안에서 사용하는 `this` 는 Vue 인스턴스를 가리킵니다
      alert('Hello ' + this.name + '!')
      // `event` 는 네이티브 DOM 이벤트입니다
      if (event) {
        alert(event.target.tagName)
      }
    }
  }
});

v-onclick 이벤트가 발생하는지 듣고 있다가 click 이벤트가 발생하면, methods에 정의한 greet 함수를 실행하는 예제입니다. 결과는 CodePen에서 확인 할 수 있습니다.

3. 인라인 메소드 핸들러

메소드 이름을 v-on에 직접 바인딩 하는 대신 인라인 JavaScript를 사용하여 methods의 함수를 호출 할 수도 있습니다.

<div id="app">
  <button v-on:click="say('hi')">Say hi</button>
  <button v-on:click="say('what')">Say what</button>
</div>
new Vue({
  el: '#app',
  methods: {
    say: function (message) {
      alert(message)
    }
  }
});

위의 코드 같이 v-on 이벤트 리스너에서 methods에 정의 된 함수를 직접 호출 할 수 있습니다. 인라인으로 methods에 정의 된 함수를 호출할 때 DOM 이벤트 객체를 사용해야 할 필요가 있을 때가 있습니다. $event라는 인자를 methods의 함수에 넘겨주어 DOM 이벤트 객체를 사용할 수 있습니다.

<div id="app">
  <button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button>
</div>
new Vue({
  el: '#app',
  methods: {
    warn: function (message, event) {
      // 이제 네이티브 이벤트에 액세스 할 수 있습니다
      if (event) event.preventDefault()
      alert(message)
    }
  }
});

인라인 메소드 핸들러 예제는 CodePen에서 확인 할 수 있습니다.

4. 이벤트 수식어

이벤트 핸들러 내부에서 종종 event.preventDefault()event.stopPropagation() 를 호출할 때가 있습니다. Vue에서도 마찬가지로 preventDefaultstopPropagation을 사용해야 할 때가 있습니다. 그 때에 이벤트 핸들러 내부에서 이벤트 객체를 사용할 수도 있지만 v-on 이벤트 리스너에서 사용할 수도 있습니다.

  • .stop
  • .prevent
  • .capture
  • .self
  • .once

v-on 뒤에 위와 같이 점(.)으로 시작하는 접미사를 사용하면 됩니다.

<!-- 클릭 이벤트 전파가 중단됩니다 -->
<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>

이벤트 수식어를 사용한 순서대로 적용되기 때문에 여러개의 수식어를 사용 할 때 수식어 사용 순서를 고려해야 합니다. 즉 @click.prevent.self를 사용하면 클릭 이벤트가 발생 했을 때 모든 엘리먼트의 기본 동작을 막을 수 있지만, @click.self.prevent는 엘리먼트 자체의 기본 동작만 막을 수 있습니다.

.once

2.1.4에 추가된 이벤트 수식어입니다.

<!-- 클릭 이벤트는 최대 한번만 트리거 됩니다. -->
<a v-on:click.once="doThis"></a>

네이티브 DOM 이벤트에서만 동작하는 다른 수식어와 달리 .once 수식어는 컴포넌트 이벤트(컴포넌트에서 발생하는 사용자 정의 이벤트)에서도 사용할 수 있습니다.

.passive

2.3.0 이후에 추가된 이벤트 수식어입니다. 모바일 환경에서 성능향상에 도움이 되는 이벤트 수식어 입니다.

<!-- 스크롤의 기본 이벤트를 취소할 수 없습니다. -->
<div v-on:scroll.passive="onScroll">...</div>

지정한 이벤트 핸들러에서 event.preventDefault()를 호출하지 않는 다는 것을 브라우저에 알리는 이벤트 수식어입니다. .passive 이벤트 수식어가 없다면 event.preventDefault()가 호출 될 수도 있기 때문에, 이벤트 핸들러가 동작이 완료 된 후 스크롤됩니다.

5. 키 수식어

키보드 이벤트를 처리할 때, 특정 키 코드를 확인 해야 할 때가 있습니다. Vue는 키 수식어를 사용하여 특정 키 코드를 처리할 수 있습니다.

<!-- keyCode가 13일 때만 `vm.submit()`을 호출합니다  -->
<input v-on:keyup.13="submit">

Vue는 자주 사용하는 키 코드의 별칭을 제공합니다.

  • .enter
  • .tab
  • .delete (Delete와 Backspace 키 모두 캡처합니다)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

위의 리스트는 키 수식어의 별칭 목록입니다. config.keyCodes 객체를 통해 사용자 지정 키 수식어 별칭을 지정할 수 있습니다.

// `v-on:keyup.f1`을 사용할 수 있습니다.
Vue.config.keyCodes.f1 = 112

오토매틱 키 수식어

이 기능은 2.5.0 이상의 Vue 버전에서 추가 된 기능입니다. KeyboardEvent.key를 통해 노출된 유효 키 이름을 수식어로 사용 할 수 있습니다.

<input @keyup.page-down="onPageDown">

위 예제에서 핸들러는 $event.key === 'PageDown' 일 때만 호출 됩니다.

참고 -

일부 키(.esc와 모든 화살토 키)는 IE9에서 일관성 없는 key 값을 가집니다. IE9를 지원해야 하는 경우 내장 별칭을 사용하는 것이 좋습니다.

6. 시스템 키 수식어

2.1.0 이상의 버전에서 추가된 기능입니다.

  • .ctrl
  • .alt
  • .shift
  • .meta

위의 수식어를 사용해 해당 수식어 키가 눌러진 경우에는 마우스 또는 키보드 이벤트 리스너를 트리거 할 수 있습니다.

<!-- Alt + C -->
<input @keyup.alt.67="clear">

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

시스템 키 수식어는 keyup 이벤트와 함께 사용되면 이벤트가 발생할 때 수식어 키가 눌려있어야 합니다. 즉, key.ctrlctrl을 누른 상태에서 키를 놓으면 트리거 됩니다. ctrl 키만 놓으면 트리거 되지 않습니다.

.exact

2.5.0 이상의 버전에서 추가된 기능입니다.

.exact 수식어를 사용하여 다른 시스템 수식어와 조합해 그 핸들러가 실행되기 위한 정확한 조합을 만들 수 있습니다.

<!-- Alt 또는 Shift와 함께 눌린 경우에도 실행됩니다. -->
<button @click.ctrl="onClick">A</button>

<!-- Ctrl 키만 눌려있을 때만 실행됩니다. -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 아래 코드는 시스템 키가 눌리지 않은 상태인 경우에만 작동합니다. -->
<button @click.exact="onClick">A</button>

마우스 버튼 수식어

2.2.0 이상의 버전에서 추가된 기능입니다.

  • .left
  • .right
  • .middle

위의 수식어는 특정 마우스 버튼이 트리거 되었을 때 이벤트 핸들러를 실행합니다.

7. HTML 이벤트 리스너를 사용할까?

Vue에서 사용하는 이벤트 리스너 등록 방법은 관심사 분리(separation of concerns) 규칙에 어긋난다고 생각할 수 있습니다. (관심사 분리란 JavaScript와 HTML, CSS 분리하는 것, 즉 각각의 역할 별로 분리하는 것을 말합니다.)

v-on을 사용하여 이벤트를 핸들링하는 몇가지 장점이 있습니다.

1) 핸들러 함수를 찾는 것이 쉽습니다.

HTML 템플릿을 간단히 하여 JavaScript 코드 내에서 핸들러 함수를 찾는 것이 더 쉽습니다.

2) 순수 로직만 가질 수 있습니다.

ViewModel 코드는 순수한 로직만 가지게 됩니다. 또한 JavaScript에서 이벤트 리스너를 수동으로 연결 할 필요가 없으므로 DOM이 필요 없게 됩니다.

3) 모든 이벤트 리스너가 자동으로 제거됩니다.

ViewModel이 파기되면 모든 이벤트 리스너가 자동으로 제거됩니다. 이벤트 제거에 대한 걱정이 필요 없게 됩니다.

참고

'Vue.JS' 카테고리의 다른 글

[Vue.JS] 컴포넌트 (기본)  (3) 2019.01.16
[Vue.JS] 폼 입력 바인딩  (0) 2018.12.15
[Vue.JS] 리스트 렌더링  (0) 2018.11.25
[Vue.JS] 조건부 렌더링  (0) 2018.11.20
[Vue.JS] 클래스와 스타일 바인딩  (0) 2018.11.13
댓글
공지사항
최근에 올라온 글