
사용자에게 웹 사이트를 좀 더 동적인 느낌을 주기 위해선 이벤트 핸들링이 필요합니다. Vue에서는 이런 이벤트 처리를 좀 더 간단하게 할 수 있게 v-on
디렉티브를 지원합니다. 자세히 알아볼까요?
v-on 미리보기
Javascript의 이벤트 핸들링
Javascript에서는 addEventListener로 이벤트를 처리합니다. 만약 button 태그에 대한 이벤트처리를 하고 싶다면 다음과 같이 했습니다.
const button = document.querySelector("button");
button.addEventListener("click", function() {
// 이벤트 처리
});
프로젝트가 커지다보면 어디서 button에 대한 이벤트를 처리하는 지 찾기 어려운 문제가 있습니다.
v-on
v-on
디렉티브는 태그의 속성에 처리할 함수를 넣기 때문에 해당 태그의 이벤트 처리가 어떤 함수에서 이뤄지는지 쉽게 알 수 있습니다.
v-on 문법
<태그 v-on:이벤트="함수"></태그>
click
, keyup
등 Javascript에서 사용하는 이벤트명과 동일합니다.v-on 약식
@
기호를 통해 줄여서 사용할 수도 있습니다.
<태그 @이벤트="함수"></태그>
예제
간단하게 button이 있고 클릭시 버튼의 값이 1씩 증가하도록 만들어보겠습니다.
<template>
<div id="app">
<button @click="counter++">{{ counter }}</button>
</div>
</template>
<script>
export default {
data() {
return {
counter: 0,
}
}
};
</script>
클릭하면 숫자가 증가하는 것을 볼 수 있습니다.
함수 대신 @click=”counter++”
처럼 Javascript 표현식을 넣어도 됩니다. 함수를 사용한다면 다음과 같이 하면 됩니다.
<template>
<div id="app">
<button @click="increaseCounter">{{ counter }}</button>
</div>
</template>
<script>
export default {
data() {
return {
counter: 0,
}
},
methods: {
increaseCounter() {
this.counter++;
}
}
};
</script>
v-on 한 이벤트에 여러 함수 사용하기
함수를 여러 개 사용하고 싶다면 comma(,
)로 구분해주시면 됩니다.
<태그 @이벤트="함수1($event), 함수2($event)"></태그>
methods: {
함수1() {
// 처리...
},
함수2() {
// 처리...
},
}
함수 입력으로 $event
가 들어가는 것이 보이는데요. 꼭 넣어주셔야 두 개가 같이 실행됩니다.
서로 다른 이벤트라면 몇 개든 넣을 수 있지만, 동일한 이벤트에 대한 처리는 v-on 한 개만 사용할 수 있습니다.

v-on event 값
addEventListener를 사용해보셨으면 알겠지만 이벤트를 처리하는 함수는 event값을 받을 수 있는데요.
addEventListener("click", function (e) {
console.log(e);
});
눌렀던 키값이나 마우스가 클릭된 위치등을 알 수 있습니다.

Vue도 마찬가지로 이 값을 전달받습니다. increaseCounter 에서 아무값도 넣지 않으면 첫 번째 파라미터는 $event
값이 들어갑니다.
methods: {
increaseCounter(e) {
this.counter++;
console.log(e)
}
}
v-on 파라미터 전달하기
이벤트 값뿐만 아니라 다른 원하는 값을 전달할 수 있습니다.
<태그 v-on:click="함수(전달값1, 전달값2, ...)"></태그>
함수를 만들 때 파라미터를 추가해주면 됩니다.
methods: {
함수(파라미터1, 파라미터2, ...) {
// 처리처리!
}
}
Q) 그러면 event 값은 어떻게 되죠?
A) 첫 번째 값은 전달받은 값으로 바뀌게 됩니다. event 값이 필요하다면 전달할 때 함수($event, 전달값1, …)
이런식으로 전달해주면 됩니다.
v-on 이벤트 수식어
태그마다 이벤트가 발생했을 때 동작하는 특정 기능이 있을 수 있습니다. 예를 들어 form
태그는 submit
이벤트 이후 페이지를 새로고침합니다. Javascript에서는 이러한 동작을 막기 위해 preventDefault
라는 함수를 썼었습니다.
const form = document.querySelector("form");
form.addEventListener((e) => {
e.preventDefault(); // 기본 동작 막기
});
이렇게 자주 일어나는 것들(캡쳐링, 버블링 등)을 쉽게 처리할 수 있도록 도와주는 것이 바로 수식어입니다.
<p v-on:이벤트.수식어="함수"></p>
이 때 함수 없이도 사용 가능합니다.
<p v-on:이벤트.수식어></p>
수식어들은 다음과 같이 있습니다.
stop
: 이벤트 전파를 막아줍니다. (stopPropagation())prevent
: 태그의 기본 동작을 막아줍니다. (preventDefault())capture
: 하위 태그에서 발생하는 이벤트를 처리하기 전에 여기서 먼저 처리합니다.self
: 자식이 아닌 해당 태그 자체의 이벤트가 발생할 때만 처리합니다.once
: 이벤트를 발생했을 때 한 번만 처리합니다.passive
: passive 기능을 켭니다. passive에 대한 자세한 설명은 MDN을 참조해주세요.수식어 체이닝
수식어는 체이닝(chaining)이 가능합니다. 예를 들어 클릭에 대한 이벤트를 한 번만 실행하고 기본 동작을 막고싶다면 다음과 같이 하면 됩니다.
<p v-on:click.once.prevent="함수"></p>
마우스 수식어
기능에 대한 수식어 뿐만 아니라, 마우스에 대한 수식어도 있습니다.
left
: 왼쪽 클릭 시 처리right
: 오른쪽 클릭 시 처리middle
: 휠 클릭 시 처리 <p v-on:click.left="함수"></p>
<p v-on:click.right="함수"></p>
<p v-on:click.middleas="함수"></p>
키보드 수식어
마우스가 있다면 키보드도 있겠죠? 키보드는 눌릴 것들이 많기 때문에 그만큼 수식어도 많습니다.
enter
tab
delete
(delete, backspace 포함)esc
space
up
down
left
right
ctrl
alt
shift
meta
(맥: command 키, 윈도우: 윈도우키)그 외에도 영어 키(a ~ z)도 있습니다. 하지만 숫자는 없으니 ASCII 값을 통해 사용해주세요. 그 외에도 F1 키같은 특별키나 숫자를 사용하고 싶다면 keyCode 값을 사용합니다.
<input v-on:keyup.112="submit" />
exact 수식어
복사 기능을 만들려고 v-on:keyup.ctrl.c
를 추가한다고 할 때 한 가지 문제가 발생합니다. shift+ctrl+c
조합으로 해도 함수가 실행이 되기 때문이죠. ctrl + c 조합으로만 눌렀을 때 동작하게 하려면 exact
수식어를 사용하면 됩니다.
<!-- 아래코드는 Alt 또는 Shift와 함께 눌렀을 때도 실행됩니다.-->
<button @click.ctrl="onClick">A</button>
<!-- 아래코드는 Ctrl키만 눌려져 있을 때 실행됩니다.-->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 아래 코드는 시스템 키가 눌리지 않은 상태인 경우에만 작동합니다.-->
<button @click.exact="onClick">A</button>
위 코드 예제는 Vue 공식문서를 참조했습니다.
마무리하며
기존 Javascript의 addEventListener와 달리 태그에 핸들러 함수를 넣으니 어디서 이벤트를 처리하는지 쉽게 알 수 있습니다. 또 태그를 querySelector로 찾을 필요도 없죠. 심지어 이벤트 제거에 대한 걱정도 없습니다. 해당 컴포넌트가 없어지면 이벤트도 같이 자동으로 제거되거든요!