[Vue] 이벤트 수식어

youngseo·2022년 5월 1일
0
post-thumbnail

한 번에 끝내는 프론트엔드 개발 초격차 패키지 Online를 들으며 정리한 내용입니다.

이벤트 수식어

1. 이벤트 수식어의 종류

이벤트 핸들러 내부에서 event.preventDefault() 또는 event.stopPropagation()를 호출하는 것은 매우 보편적인 일입니다. 메소드 내에서 쉽게 이 작업을 할 수 있지만, DOM 이벤트 세부 사항을 처리하는 대신 데이터 로직에 대한 메소드만 사용할 수 있으면 더 좋습니다.

이 문제를 해결하기 위하여, Vue는 v-on이벤트에 이벤트 수식어를 제공합니다. 수식어는 점으로 된 접미사 입니다.

1-1 수식어 종류

.stop
.prevent
.capture
.self
.once
.passive

1-2. 수식어 체이닝

아래와 같이 체이닝으로 작성할 수도 있습니다.

@click.prevent.once="handler">  //html의 기본 동작도 제어하고 단 1회만 실행될 수 있도록 합니다.

2. event.prevetnDefault

2-1 event.prevetnDefault 기본개념

<template>
  <a
    href="https://naver.com"
    target="_blank"
    @click="handler">
    Naver</a>
</template>
<script>
export default {
  methods: {
    handler(event) {
      event.preventDefault()
      console.log('ABC!')
    }
  }
}
</script>

preventDefault메소드를 실행했기 때문에, a태그를 눌러도 네이버 페이지로 이동하지 않습니다.

이렇게 event.preventDeault() 메소드를 이용하면 이미 html에 있는 기능을 동작시키지 않고, 메소드만 실행하게 만들 수 있습니다.

2-2. prevent이벤트 수식언

앞서 본 event.preventDefault메소드 대신 vue.js의 prevent이벤트 수식어를 이용해 조금 더 단순화해 사용할 수 있습니다.

<template>
  <a
    href="https://naver.com"
    target="_blank"
    @click.prevent="handler">
    Naver</a>
</template>
<script>
export default {
  methods: {
    handler() {
      console.log('ABC!')
    }
  }
}
</script>

3. once이벤트 수식언

특정 이벤트를 발생했을 때 해당하는 메소드를 단 1회만 실행해줍니다.

4.이벤트 버블링

4-1 이벤트 버블링 기본 개념

아래 코드를 싱행한 후 parent 영역 클릭시 콘솔창에는 A가 출력이 되고 child 영역 클릭시 콘솔창에는 B 다음으로 A가 출력되게 됩니다.

자식 요소를 클릭하면 결국 이를 포함하고 있는 부모 요소를 클릭하는 것과 마찬가지로 위의 요소를 타고 타고 올라가서 전파를 한다는 의미로 이를 이벤트 버블링이라고 부릅니다.

<template>
  <div
    class="parent"
    @click="handlerA">
    <div
      class="child"
      @click="handlerB"></div>
  </div>
</template>
<script>
export default {
  methods: {
    handlerA() {
      console.log('A')
    },
    handlerB() {
      console.log('B')
    }
  }
}
</script>
<style scoped lang="scss">
  .parent {
    width: 200px;
    height: 100px;
    background-color: royalblue;
    margin: 10px;
    padding: 10px;
    .child {
      width: 100px;
      height: 100px;
      background-color: orange;
    }
  }
</style>

4-2. 이벤트 버블링 방지: event.stopPropagation()

만약, child만 클릭하고 parents는 동작하지 않도록 하고 싶다면 event.stopPropgation을 이용해 이벤트 버블링을 방지 할 수 있습니다.

<script>
export default {
  methods: {
    handlerA() {
      console.log('A')
    },
    handlerB(event) {
      event.stopPropagation()
      console.log('B')
    }
  }
}
</script>

4-3. stop수식어 이벤트

<template>
  <div
    class="parent"
    @click="handlerA">
    <div
      class="child"
      @click.stop="handlerB"></div>
  </div>
</template>

5. 이벤트 캡쳐링

5-1 이벤트 캡쳐링 기본 개념

이벤트 캡쳐링은 위의 이벤트 버블링과 반대되는 개념으로 바로 부모 요소에서 자식 요소로 내려오는 개념입니다.

5-2 capture 이벤트 수식어

기존 예시 코드에서 자식 요소를 클릭했을 때 부모요소의 메소드가 먼저 실행되고 자식 요소의 메소드가 실행되게 하고 싶다면, .capture라는 이벤트 수식어를 적용하면 됩니다.

<template>
  <div
    class="parent"
    @click.capture="handlerA">
    <div
      class="child"
      @click="handlerB"></div>
  </div>
</template>

6. self 이벤트 수식어

<template>
  <div
    class="parent"
    @click.self="handlerA">
    <div
      class="child"></div>
  </div>
</template>

클릭 이벤트를 부모요소에만 남긴 후 자식요소를 클릭해보면, 자식요소 부분을 아무리 클릭해도 콘솔창에는 아무런 내용이 확인되지 않는 것을 확인할 수 있습니다.

하지만 자식요소를 포함하고 있지 않는 부모 요소 부분을 클릭하면 콘솔창에 A가 정상적으로 출력되는 것을 확인할 수 있습니다.

self란 self라는 수식어가 부터 있는 그 클릭이라는 이벤트가 붙어 있는 그 parent 영역을 정확하게 클릭했을 때 동작하게 만들어주는 것입니다.

자식 요소가 부모요소에 포함되고 있기 때문에 부모요소의 메소드가 실행되게 됩니다.

6-2 event.target() & event.currentTarget()

조금 더 자세히 살펴보기 위해 event.target()메소드와 event.currentTarget()메소드를 살펴보도록 하겠습니다.

target은 실제로 클릭이 된 요소를 지칭하며, currentTarget은 실행된 해당하는 함수에 연결이 되어져 있는 그 이벤트의 해당하는 요소가 출력되게 됩니다.

<script>
export default {
  methods: {
    handlerA(event) {
      console.log(event.target)
      console.log(event.currentTarget)
      console.log('A')
    },
    handlerB() {
      console.log('B')
    }
  }
}
</script>

오렌지 색 영역을 클릭해보면, 아래와 같이 event.target은 자식요소에 해당하는 부분이, event.currentTarget의 경우 부모요소에 해당하는 부분이 출력되었습니다.

하지만 파란색 영역을 클릭해보면, event.targetevent.currentTarget 모두 부모요소에 해당하는 부분이 출력되는 것을 확인할 수 있습니다.

6-3 self 이벤트 수식어 정리

self이벤트 수식어를 이용하면 자식 요소를 클랙해도 부모요소의 메소드가 실행되지 않게 됩니다.

실제로 클릭된 부분과 그 클릭이라는 이벤트가 연결된 해당하는 요소가 같은 경우에만 그 연결된 메소드가 실행이 되게 됩니다.

7. passive이벤트 수식어

로직 처리에 부하를 주는 코드를 작성해보았습니다. 화면의 구현과 이에 해당하는 로직이 브라우저가 동시에 처리하기 때문에 로직이 복잡하고 양이 많다면 그만큼 부하가 발생하게 됩니다.

<template>
  <div
    class="parent"
    @wheel="handler">
    <div class="child"></div>
  </div>
</template>
<script>
export default {
  methods: {
    handler(event) {
      for(let i=0; i<10000; i+=1){
      console.log(event)
      }
    }
  }
}
</script>
<style scoped lang="scss">
  .parent {
    width: 200px;
    height: 100px;
    background-color: royalblue;
    margin: 10px;
    padding: 10px;
    overflow: auto;  //parent요소보다 넘치는 경우 스크롤생성
    .child {
      width: 100px;
      height: 2000px;
      background-color: orange;
    }
  }
</style>

7-2 passive 이벤트 수식어

.passive라는 이벤트 수식어는 로직의 처리와 화면의 동작을 완전히 독립시켜 주게 됩니다. 이를 통해 부하를 줄일 수 있게 되는 것입니다. 화면은 부드러워보이지만, 로직은 내부적으로 따로 돌아가고 있는 구조가 되는 것입니다.

0개의 댓글