이벤트 핸들러 내부에서 event.preventDefault() 또는 event.stopPropagation()를 호출하는 것은 매우 보편적인 일입니다. 메소드 내에서 쉽게 이 작업을 할 수 있지만, DOM 이벤트 세부 사항을 처리하는 대신 데이터 로직에 대한 메소드만 사용할 수 있으면 더 좋습니다.
이 문제를 해결하기 위하여, Vue는 v-on이벤트에 이벤트 수식어를 제공합니다. 수식어는 점으로 된 접미사 입니다.
모든 클릭을 막을 수 있다
<template>
<a
href="https://naver.com"
target="_blank"
@click.prevent="handler">
Naver
</a>
</template>
<script>
export default {
methods: {
handler() {
console.log('ABC!')
}
}
}
</script>
click event가 발생하더라도 handler는 실행되지 않음
<template>
<a
href="https://naver.com"
target="_blank"
@click.once="handler">
Naver
</a>
</template>
<script>
export default {
methods: {
handler() {
console.log('ABC!')
}
}
}
</script>
수식어 체이닝을 통해 여러가지 수식어를 함께 사용 가능하다.
<template>
<a
href="https://naver.com"
target="_blank"
@click.prevent.once="handler">
Naver
</a>
</template>
<script>
export default {
methods: {
handler() {
console.log('ABC!')
}
}
}
</script>
내가 클릭한 영역과 별개로 나를 포함한 영역까지 확장되어서
handler
가 동작하는 것을 이벤트 버블링이라고 한다
stopPropagation()
을 실행시켜 버블링을 방지할 수 있다.
이는.stop
과 같은 실행 방법
.<template>
<div
class="parent"
@click="handlerA">
<div
class="child"
@click="handlerB">
</div>
</div>
</template>
<script>
export default {
methods: {
handlerA() {
console.log('A')
},
handlerB(event) {
event.stopPropagation()
console.log('B')
}
}
}
</script>
이 로직을 .stop
을 이용하여
<template>
<div
class="parent"
@click="handlerA">
<div
class="child"
@click.stop="handlerB">
</div>
</div>
</template>
<script>
export default {
methods: {
handlerA() {
console.log('A')
},
handlerB() {
console.log('B')
}
}
}
</script>
이렇게 간단하게 해결 가능함
버블링과 반대되는 개념, B, A로 출력되었던 내용을 A,B로 출력
<template>
<div
class="parent"
@click.capture="handlerA">
<div
class="child"
@click="handlerB">
</div>
</div>
</template>
<script>
export default {
methods: {
handlerA() {
console.log('A')
},
handlerB() {
console.log('B')
}
}
}
</script>
자기 자신인 정확한 영역을 클릭했을 때 이벤트가 동작하게 만든다.
즉,target
과currentTarget
이 동일한 경우만 이벤트가 동작
<template>
<div
class="parent"
@click="handlerA">
<div
class="child">
</div>
</div>
</template>
<script>
export default {
methods: {
handlerA(e) {
// target은 실제로 클릭이 된 요소를 지칭
console.log(e.target)
// 실행된 함수에 연결이 되어있는 이벤트에 연결되어져있는 요소가 출력
console.log(e.currentTarget)
console.log('A')
},
handlerB() {
console.log('B')
}
}
}
</script>
기본적인 로직의 처리와 내가 요청한 scroll 처리를 분리해줌
쾌적한 서비스를 제공할 수 있음, 최대 5배 정도 속도가 빨라짐
<template>
<div
class="parent"
@wheel.passive="handler">
<div
class="child">
</div>
</div>
</template>
<script>
export default {
methods: {
handler(e) {
for (let i = 0; i < 10000; i += 1){
console.log(e)
}
}
}
}
</script>
<style lang="scss" scoped>
.parent {
width: 200px;
height: 100px;
background-color: royalblue;
margin: 10px;
padding: 10px;
overflow: auto;
.child {
width: 100px;
height: 2000px;
background-color: orange;
}
}
</style>
console.log
가 10,000
번씩 찍히는 상황. 이로인해 스크롤 내릴 때 마다 엄청나게 버벅인다. 하지만 passive
를 사용하면 @wheel
과 console
을 분리하여 쾌적하게 사용 가능하다.