Development/Vue.js

[Vue.js] Document 따라하기 - Event Handling

도롱뇽도롱 2022. 6. 15. 18:00
반응형

Listening to Events

일반적으로 @ 기호로 사용되는 v-on 지시문은 DOM 이벤트를 수신하고 트리거 될 때 사전 정의해둔 JavaScript 코드를 실행시킨다. 'v-on:click="handler"' 또는 줄여서 '@click="handler"'와 같이 사용한다.

핸들러 값은 다음 중 하나일 수 있다.

  1. 인라인 핸들러: 이벤트가 트리거 될 때 실행되는 인라인 JavaScript(네이티브 onclick 속성과 유사)
  2. 메서드 핸들러: Component에 정의된 메서드 이름 또는 메서드를 가리키는 경로

 

Inline Handlers

인라인 핸들러는 일반적으로 다음과 같은 간단한 경우에 사용된다.

data() {
  return {
    count: 0
  }
}
<button @click="count++">Add 1</button>
<p>Count is: {{ count }}</p>

v-on
v-on

 

Method Handlers

이벤트 핸들러 대부분의 논리는 더 복잡할 것이며 인라인 핸들러에서는 실현 가능하지 않을 수 있다. 그러므로 v-on은 component의 메서드 이름이나 메서드를 가리키는 경로를 실행할 수 있게 구현되어 있다.

 

예를 들어

data() {
  return {
    name: 'Vue.js'
  }
},
methods: {
  greet(event) {
    // 메소드 내부의 `this` 현재 활성 인스턴스를 가리킴
    alert(`Hello ${this.name}!`)
    // `event` is the native DOM event
    if (event) {
      alert(event.target.tagName)
    }
  }
}
<!-- `greet`은 상단에서 정의된 메서드의 이름 -->
<button @click="greet">Greet</button>

v-on with method handler
v-on with method handler

메서드 핸들러는 이를 트리거하는 네이티브 DOM 이벤트 객체를 자동으로 수신한다. 위의 예에서 event.target.tagName을 통해 이벤트를 전달하는 element에 액세스 할 수 있다.

v-on with method handler

 

Method vs. Inline Detection

템플릿 컴파일러는 v-on 값 문자열이 유효한 JavaScript 식별자 또는 속성에 접근할 수 있는 경로인지 확인하여 메서드 핸들러를 감지한다. 예를 들어, foo, foo.bar, foo['bar']는 머세드 핸들러로 처리되는 반면 foo(), count++은 인라인 핸들러로 처리된다.

 

Calling Methods in Inline Handlers

메서드 이름을 직접 바인딩하는 대신 인라인 핸들러에서 메서드를 호출할 수도 있다. 이를 통해 네이티브 이벤트 객체 대신 사용자 지정 인수를 메서드에 전달할 수 있다.

methods: {
  say(message) {
    alert(message)
  }
}
<button @click="say('hello')">Say hello</button>
<button @click="say('bye')">Say bye</button>

Calling Methods in Inline Handlers
Calling Methods in Inline Handlers

 

Accessing Event Argument in Inline Handlers

때로는 인라인 핸들러에서 네이티브 DOM 이벤트 객체에 액세스해야 하는 경우도 있다. 특수한 키워드인 $event를 사용하여 메서드에 전달하거나 인라인 화살표 함수를 사용할 수 있다.

<!-- $event 사용 -->
<button @click="warn('Form cannot be submitted yet.', $event)">
  Submit
</button>

<!-- 인라인 화살표 함수 사용 -->
<button @click="(event) => warn('Form cannot be submitted yet.', event)">
  Submit
</button>
methods: {
  warn(message, event) {
    // 이제 네이티브 이벤트 객체에 접근 가능
    if (event) {
      event.preventDefault()
    }
    alert(message)
  }
}

Accessing Event Argument in Inline Handlers
Accessing Event Argument in Inline Handlers

 

Event Modifiers

이벤트 핸들러 내에서 event.preventDefault() 또는 event.stopPropagation()을 호출하는 것은 매우 일반적이다. 메서드 내에서 이 작업을 쉽게 수행할 수 있지만, 메서드가 DOM 이벤트 세부 정보를 처리하는 것보다 오로지 데이터 처리 로직만 있다면 유지보수에 더 좋을 것이다.

 

이 문제를 해결하기 위해 Vue는 v-on에 대한 점(.)으로 시작하는 지시적 접미사인 이벤트 수식어를 제공한다.

  • .stop
  • .prevent
  • .self
  • .capture
  • .once
  • .passive
<!-- 클릭 이벤트의 전파 중지 -->
<a @click.stop="doThis"></a>

<!-- submit 이벤트가 더 이상 페이지를 리로드 하지 않음 -->
<form @submit.prevent="onSubmit"></form>

<!-- 수식어는 연결 가능 -->
<a @click.stop.prevent="doThat"></a>

<!-- 핸들러 없이 수식어만 사용 가능 -->
<form @submit.prevent></form>

<!-- event.target이 element 자신일 경우에만 핸들러 실행 -->
<!-- 자식 element에서 클릭 액션이 있으면 핸들러 실행되지 않음 -->
<div @click.self="doThat">...</div>

tip. 수식어를 명시한 순서대로 관련 코드가 생성되기 때문에 수식어를 사용할 때에는 순서가 중요하다.

@click.prevent.self를 사용하면 해당 element 및 자식 element가 클릭되는 경우 실행되는 기본 동작을 방지하지만, @click.self.prevent는 해당 element가 클릭되는 경우에만 실행되는 기본 동작을 방지한다.

 

.capture, .once, .passive 수식어는 네이티브 addEventListener 메서드의 옵션을 미러링 한다.

<!-- 이벤트 리스너를 추가할 때 capture mode 사용 -->
<!-- 내부 element에서 클릭 이벤트 핸들러가 실행되기 전에 여기에서 먼저 실행됨 -->
<div @click.capture="doThis">...</div>

<!-- 클릭 이벤트는 단 한 번만 실행된다. -->
<a @click.once="doThis"></a>

<!-- 핸들러 내 event.preventDefault()가 포함되었더라도 스크롤 이벤트의 기본 동작(스크롤) 발생 -->
<div @scroll.passive="onScroll">...</div>

.passive 수식어는 일반적으로 모바일 장치의 성능 향상을 위해 터치 이벤트 리스너와 함께 사용된다.

 

tip. .passive는 브라우저에게 이벤트의 기본 동작을 방지(prevent)하지 않겠다는 의도를 전달한 것이다. 따라서 .passive와 .prevent를 함께 사용해서는 안되며, 그렇게 할 경우 콘솔에서 경고 메시지를 볼 수 있다.

 

Key Modifiers

키보드 이벤트를 수신할 때 특정 키를 확인해야 하는 경우가 많다. Vue는 키 이벤트를 수신할 때 v-on 또는 @에 대한 키 수식어를 추가할 수 있다.

<!-- enter key를 눌렀을 때만 `vm.submit()` 호출 -->
<input @keyup.enter="submit" />

Key Modifier
Key Modifier

KeyboardEvent.key를 통해 유효한 입력키 이름을 kebab-case로 변환하여 수식어로 사용할 수 있다.

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

위의 예에서 핸들러는 $event.key가 PageDown일 경우에만 호출된다.

KeyboardEvent.key
KeyboardEvent.key

 

Key Aliases

Vue는 가장 일반적으로 사용되는 키에 대한 별칭을 제공한다.

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

 

System Modifier Keys

다음 수식어를 사용하여 해당 수식어 키를 누를 때만 마우스 또는 키보드 이벤트 리스너를 트리거할 수 있다.

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

Macintosh 키보드에서 메타는 command 키(⌘)이며 Windows 키보드에서 meta는 Windows 키(⊞)이다.

 

예를 들면

<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />

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

tip. 수식어 키는 일반 키와 다르며 keyup 이벤트와 함께 사용되는 경우 이벤트가 발생할 때 눌려져 있어야 한다. 즉, keyup.ctrl은 ctrl을 누른 상태에서 다른 키를 놓는 경우에만 트리거 된다. ctrl 키만 놓으면 트리거 되지 않는다.

System Modifier Keys
System Modifier Keys

 

.exact Modifier

.exact 수식어를 사용하면 이벤트를 트리거하는 데 필요한 시스템 수식어의 정확한 조합을 제어할 수 있다.

<!-- Alt 또는 Shift를 함께 눌러도 실행 -->
<button @click.ctrl="onClick">A</button>

<!-- Ctrl 키를 누르고 다른 키를 누르지 않은 경우에만 실행 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 시스템 수식어를 누르지 않은 경우에만 실행 -->
<button @click.exact="onClick">A</button>

 

Mouse Button Modifiers

  • .left
  • .right
  • .middle

특정 마우스 버튼에 의해 이벤트가 트리거 되도록 제한할 때 사용한다.

 

 

관련 Repo

https://github.com/galaxyuliana/VueExercises/tree/master/first-vue-project/src/components/Exercise/07

 

참고 자료

https://vuejs.org/guide/essentials/event-handling.html

반응형