이벤트 처리(Event Handling)
이벤트 처리(Event Handling)
사용자가 버튼을 누르고, 폼을 제출하고, 키를 입력하는 순간마다 앱은 반응해야 해요. Vue에서는 v-on 디렉티브(보통 @로 줄여 씀)로 DOM 이벤트를 듣고, 트리거되면 JavaScript를 실행하게 해요. 이벤트 리스너, 인라인·메서드 핸들러, 그리고 각종 수식어를 정리할게요.
이벤트 듣기
사용법은 v-on:click="handler" 또는 축약형 @click="handler"예요. 핸들러 값은 두 종류가 있어요.
- 인라인 핸들러 — 이벤트가 트리거될 때 실행될 인라인 JavaScript (네이티브
onclick속성과 유사). - 메서드 핸들러 — 컴포넌트에 정의된 메서드를 가리키는 속성 이름이나 경로.
<button @click="count++">Add 1</button>
<p>Count is: {{ count }}</p>
로직이 복잡하면 메서드 핸들러를 써요.
function greet(event) {
alert(`Hello ${name.value}!`)
// event 는 네이티브 DOM 이벤트
if (event) {
alert(event.target.tagName)
}
}
<button @click="greet">Greet</button>
메서드 핸들러는 자동으로 트리거한 네이티브 DOM 이벤트 객체를 받아요. 템플릿 컴파일러는 v-on 값이 유효한 JavaScript 식별자나 속성 접근 경로인지 확인해서 메서드 핸들러인지 인라인 핸들러인지 판별해요. foo, foo.bar, foo['bar']는 메서드 핸들러로, foo()나 count++는 인라인 핸들러로 처리돼요.
인라인 핸들러에서 메서드 호출·이벤트 인자
인라인 핸들러에서 메서드를 호출하면 네이티브 이벤트 대신 커스텀 인자를 전달할 수 있어요.
<button @click="say('hello')">Say hello</button>
원본 DOM 이벤트가 필요하면 특별 변수 $event로 넘기거나 인라인 화살표 함수를 써요.
<button @click="warn('Form cannot be submitted yet.', $event)">Submit</button>
<button @click="(event) => warn('Form cannot be submitted yet.', event)">Submit</button>
이벤트 수식어(event.preventDefault() etc.)
핸들러 안에서 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 이 요소 자신일 때만 핸들러 트리거 (자식 요소가 아님) -->
<div @click.self="doThat">...</div>
수식어를 쓸 때는 순서가 중요해요. @click.prevent.self는 요소 자신과 자식의 기본 동작을 모두 막고, @click.self.prevent는 요소 자신의 기본 동작만 막아요. .capture, .once, .passive는 네이티브 addEventListener의 옵션을 반영해요. .passive는 모바일 터치 리스너 성능 개선에 주로 쓰여요. .passive와 .prevent를 함께 쓰면 안 돼요.
키 수식어(Key Modifiers)
키보드 이벤트를 들을 때 특정 키를 확인해야 할 때가 많아요. Vue는 키 이벤트에 키 수식어를 추가할 수 있어요.
<!-- `key` 가 Enter 일 때만 submit 호출 -->
<input @keyup.enter="submit" />
KeyboardEvent.key로 노출된 유효한 키 이름을 kebab-case로 바꿔 수식어로 직접 쓸 수 있어요.
<input @keyup.page-down="onPageDown" />
이 예시는 $event.key가 'PageDown'일 때만 호출돼요.
키 별칭
.enter, .tab, .delete(Delete·Backspace 둘 다 캡처), .esc, .space, .up, .down, .left, .right가 제공돼요.
시스템 수식어 키
.ctrl, .alt, .shift, .meta 수식어로 해당 수식어 키가 눌린 상태에서만 마우스·키보드 리스너를 트리거해요. Mac에서 meta는 command 키(⌘), Windows에서는 Windows 키(⊞)예요.
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
.exact 수식어
.exact는 이벤트 트리거에 필요한 시스템 수식어의 정확한 조합을 제어할 수 있게 해줘요.
<!-- 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 수식어는 특정 마우스 버튼으로 트리거된 이벤트로 핸들러를 제한해요. 이 이름들은 실제 물리 버튼이 아니라 "main", "secondary", "auxiliary" 포인팅 장치 이벤트 트리거를 나타낸다는 점을 유의하세요.