[Vue3] 이벤트 핸들링

Dohee Kang·2023년 3월 4일
1

Vue

목록 보기
11/28
post-custom-banner

  • 일반적으로 v-on 디렉티브는 @ 기호를 사용하여 단축
  • v-on:click="handler" 또는 @click="handler"와 같이 사용
  • 핸들러 종류는 총 2가지 입니다.
    • 인라인 핸들러 : 이벤트가 트리거될 때 실행되는 인라인 자바스크립트
    • 메서드 핸들러 : 컴포넌트에 정의된 메서드명 또는 메서드를 가리키는 경로

1. 인라인 핸들러

  • 인라인 핸들러는 일반적으로 아래와 같이 간단한 경우에만 사용된다.
<template>
  <h3>count: {{ count }}</h3>
  <button @click="count++">Click!</button>
</template>

<script>
export default {
  name: 'App',
  data () {
    return {
      count: 0
    }
  }
}
</script>

2. 메서드 핸들러

  • 일반적으로 로직이 많고 복잡할 때 사용된다.
<template>
  <button @click="greet">Click!</button>
</template>

<script>
export default {
  name: 'App',
  data () {
    return {
      name: 'Vue.js'
    }
  },
  methods: {
    greet(event) {
      alert(`${this.name}입니다.`);
      if (event) alert(event.target.tagName);
    }
  }
}
</script>

3. 인라인 핸들러에서 메서드 호출

  • 네이티브 이벤트 객체 대신 사용자 인자를 메서드에 전달할 수 있다.
<template>
  <button @click="say('Hi!')">Click!</button>
</template>

<script>
export default {
  name: 'App',
  data () {
    return {
      name: 'Vue.js'
    }
  },
  methods: {
    say(msg) {
      alert(msg);
    }
  }
}
</script>

4. 인라인 핸들러에서 이벤트 객체 접근

  • 특수한 키워드인 $event를 사용하거나 인라인 화살표 함수를 사용하여 DOM 이벤트 객체에 접근할 수 있다.
<template>
  <button @click="warn('아직 양식을 제출할 수 없습니다.', $event)">제출하기</button>
  <button @click="(event) => warn('아직 양식을 제출할 수 없습니다.', event)">제출하기</button>
</template>

<script>
export default {
  name: 'App',
  data () {
    return {
      name: 'Vue.js'
    }
  },
  methods: {
    warn(msg, event) {
      if (event) event.preventDefault();
      alert(msg);
    }
  }
}
</script>

5. 이벤트 수식어

  • 이벤트 핸들러 내에서 일반적으로 event.preventDefault()event.stopPropagation()을 호출하는 일이 많다. 메서드 내에서 수행하는 방법도 있지만 로직 없이 오로지 데이터 처리 로직만으로 쉽게 수행할 수 있다.
  • 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 수식어는 addEventLister 메서드의 옵션을 반영한다.

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

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

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

.passive 수식어는 브라우저에게 이벤트의 기본 동작을 방지하지 않겠다는 의도를 전달하는 것이다.
그래서 .passive와 기본 동작을 방지한다는 .prevent 를 함께 사용하면 안된다.


6. 입력키 수식어

  • 특정 키에 대한 키보드 이벤트를 수신할 때 사용
<!-- key가 Enter일 때만 submit을 호출합니다 -->
<input @keyup.enter="submit" />
  • kebab-case로 변환하여 수식어로 사용할 수 있다.
<!-- Key가 PageDown일 때만 호출한다 -->
<input @keyup.page-down="onPageDown" />
  • 입력키 별칭
    • .enter, .tab, .delete(Delete 및 Backsapce 키), .esc, .space, .up, .down, .left, .right
  • 시스템 입력키 수식어
    • .ctrl, .alt, .shift, .meta
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />

<!-- Ctrl + Click -->
<div @click.ctrl="capture">캡쳐하기</div>

💡 시스템 입력키 수식어는 일반 키와 다르므로 keyup 이벤트와 함께 사용되는 경우 키가 눌러져 있어야 이벤트가 발생한다.

  • .exact 수식어
    • 이벤트를 트리거하는 데 필요한 시스템 수식어의 정확한 조합을 제어
<!-- Ctrl과 함께 Alt 또는 Shift를 누른 상태에서도 클릭하면 실행된다. -->
<button @click.ctrl="onClick">A</button>

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

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

7. 마우스 버튼 수식어

  • 특정 마우스 버튼에 의해 이벤트가 트리거 되도록 제한하고 싶을 때 사용
  • .left, .right, .middle
<!-- 왼쪽 마우스 클릭해야 실행된다. -->
<button @click.left="onClick">A</button>

<!-- 오른쪽 마우스 클릭해야 실행된다. -->
<button @click.right="onClick">A</button>

<!-- 가운데 마우스 클릭해야 실행된다. -->
<button @click.middle="onClick">A</button>
profile
오늘은 나에게 어떤 일이 생길까 ✨
post-custom-banner

0개의 댓글