blog
Vue 이벤트 핸들러: 인라인 핸들러와 메서드 핸들러의 차이
Front-end / Vue#Vue#v-on#이벤트 핸들러#React
@click="openModal('severeResult')"처럼 인자를 넘겨 호출하는 코드를 보면 "렌더링할 때 바로 실행되는 것 아닌가?" 하는 의문이 든다. React의 onClick={openModal('severeResult')}가 실제로 그렇게 동작하기 때문이다. Vue에서는 즉시 실행되지 않는다.
Vue 템플릿 컴파일러의 두 가지 처리
v-on(@)의 값은 컴파일러가 형태를 보고 다르게 처리한다.
메서드 핸들러
값이 함수 이름이나 경로(openModal, foo.bar)면 그 함수를 그대로 핸들러로 등록한다. 첫 번째 인자로 네이티브 이벤트 객체가 전달된다.
<button @click="openModal">열기</button>
<!-- 대략 onClick: openModal -->
인라인 핸들러
값이 호출식이나 문장(openModal('x'), count++, $emit('result', type))이면 컴파일러가 화살표 함수로 감싼다.
<button @click="openModal('severeResult')">열기</button>
<!-- 대략 onClick: $event => openModal('severeResult') -->
<input @change="$emit('result', answer.type)" />
<!-- 대략 onChange: $event => $emit('result', answer.type) -->
그래서 openModal('severeResult')는 클릭할 때만 실행된다. $emit이 특별 취급되는 것이 아니라, 호출식이면 모두 같은 규칙으로 감싸진다. @click="() => openModal('severeResult')"처럼 직접 감싸도 동작은 같지만 필요하지 않다.
인라인 핸들러에서 이벤트 객체 쓰기
인자와 이벤트 객체가 모두 필요하면 $event를 넘기거나 화살표 함수를 쓴다.
<button @click="openModal('severeResult', $event)">열기</button>
<button @click="(event) => openModal('severeResult', event)">열기</button>
실제로 즉시 실행되는 경우
- React JSX:
onClick={openModal('x')}는 렌더링 중에 실행된다.onClick={() => openModal('x')}로 감싸야 한다. - Vue의
v-bind로 함수 prop 전달::on-close="closeModal('x')"는v-on이 아니라 일반 바인딩이라 렌더링 때 호출되고 그 반환값이 전달된다.:on-close="() => closeModal('x')"로 감싼다. - Vue 렌더 함수/JSX:
h('button', { onClick: openModal('x') })도 즉시 실행된다.
정리
| 코드 | 처리 | 실행 시점 |
|---|---|---|
@click="openModal" | 함수 그대로 등록 | 클릭 시 (이벤트 객체 전달) |
@click="openModal('x')" | $event => openModal('x')로 감쌈 | 클릭 시 |
@change="$emit('result', v)" | $event => $emit('result', v)로 감쌈 | change 시 |
:on-close="closeModal('x')" | 일반 바인딩 | 렌더링 시 ❌ |
React onClick={openModal('x')} | 일반 표현식 | 렌더링 시 ❌ |