[Vue3] 9. 이벤트 핸들링

김관응·2023년 4월 7일
0

Vue

목록 보기
10/14

이벤트 리스닝

일반적으로 v-on 디렉티브는 단축 문법으로 @ 기호를 사용하며, DOM 이벤트를 수신하고 트리거될 때, 사전 정의해둔 JavaScript 코드를 실행할 수 있다.

아래와 같이 사용한다.

v-on:click="handler"
@click="handler"

핸들러는 두 가지 종류가 있다.

  1. 인라인 핸들러: 이벤트가 트리거될 때 실행되는 인라인 JavaScript(네이티브 onclick 속성과 유사).

  2. 메서드 핸들러: 컴포넌트에 정의된 메서드 이름 또는 메서드를 가리키는 경로.

인라인 핸들러

v-on:click="methodName" 혹은 줄여서 @click="methodName"으로 사용한다.

<template>
  <button @click="count++">1 추가</button>
  <p>숫자 값은: {{ count }}</p>
</template>

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

메서드 핸들러

더하는 것 같은 단순한건 인라인으로 처리해도 상관없지만 복잡한 방법은 아래와 같이 만들어야 한다.

<template>
	<button @click="greet">환영하기</button>
</template>

<script setup>
import { ref } from 'vue'

const name = ref('Vue.js')

function greet(event) {
  alert(`안녕 ${name.value}!`)
  // 'event'는 네이티브 DOM 이벤트 객체입니다.
  if (event) {
    alert(event.target.tagName)
  }
}
</script>

더하기 1과 같은 정말 간단한것 이외에는 모두 매서드로 만드는것이 좋을 것 같다.

호출 시 @click="이름" 이 아니라 @click="이름('파라미터')" 이렇게 파라미터를 넘겨줄 수도 있다.

이벤트 핸들러 객체 접근하기

가끔 어느 이벤트 객체에서 호출이 되었는지 알아야할 때가 있다.

<template>
  <!-- 특수한 키워드인 $event 사용 -->
  <button @click="warn('아직 양식을 제출할 수 없습니다.', $event)">
    제출하기
  </button>

  <!-- 인라인 화살표 함수 사용 -->
  <button @click="(event) => warn('아직 양식을 제출할 수 없습니다.', event)">
    제출하기
  </button>
</template>

<script setup>
import { ref } from 'vue'
function warn(message, event) {
  // 이제 네이티브 이벤트 객체에 접근할 수 있습니다.
  if (event) {
    event.preventDefault()
  }
  alert(message)
}
</script>

이벤트 수식어

이밴트 핸들러 내에 event.preventDefault() 또는 event.stopPropagation()을 호출하는것은 흔한 일이다.
아지만 메서드가 DOM에대한 이벤트가 없이 데이터처리 로직만 있으면 유지보수에 좀더 유리할 것이다.

이러한 문제를 해결하기 위해 v-on은 이벤트 수식어를 제공한다.

<!-- 클릭 이벤트 전파가 중지됩니다. -->
<a @click.stop="doThis"></a>

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

<!-- 수식어를 연결할 수 있습니다. -->
<a @click.stop.prevent="doThat"></a>

<!-- 이벤트에 핸들러 없이 수식어만 사용할 수 있습니다. -->
<form @submit.prevent></form>

<!-- event.target이 엘리먼트 자신일 경우에만 핸들러가 실행됩니다. -->
<!-- 예를 들어 자식 엘리먼트에서 클릭 액션이 있으면 핸들러가 실행되지 않습니다. -->
<div @click.self="doThat">...</div>

수식어 사용에는 순서가 중요하다.
@click.prevent.self를 사용하면 앨리먼트 자체와 그 자식에 대한 클릭의 기본 동작을 방지하는 반면, @click.self.prevent는 앨리먼트 자체에 대한 클릭의 기본 동작만 방지한다.

.capture, .once 및 .passive 수식어는 네이티브 addEventListener 메서드의 옵션을 반영한다.

<!-- 이벤트 리스너를 추가할 때 캡처 모드 사용 -->
<!-- 내부 엘리먼트에서 클릭 이벤트 핸들러가 실행되기 전에, 여기에서 먼저 핸들러가 실행됩니다. -->
<div @click.capture="doThis">...</div>

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

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

입력키 수식어

.enter
.tab
.delete ("Delete" 및 "Backspace" 키 모두 캡처)
.esc
.space
.up
.down
.left
.right
시스템 입력키 수식어
.ctrl
.alt
.shift
.meta(커멘드 키(⌘) or Windows 키(⊞)

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

<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">시작하기</div>

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

<!-- Ctrl과 함께 Alt 또는 Shift를 누른 상태에서도 클릭하면 실행됩니다. -->
<button @click.ctrl="onClick">A</button>

<!-- 오직 Ctrl만 누른 상태에서 클릭해야 실행됩니다. -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 시스템 입력키를 누르지 않고 클릭해야지만 실행됩니다. -->
<button @click.exact="onClick">A</button>

마우스 버튼 수식어

.left
.right
.middle

profile
엔지니어였던 개발자

0개의 댓글