简介
在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。
尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
大概的意思就是,我们添加一个事件,如点击事件的时候,需要考虑到事件的冒泡等,而添加了指令(事件修饰符)之后,我们就不需要去考虑这些事情了
使用
在开始前,我们先准备好一个例子,一个最简单的,两个div都有点击事件的例子,以更好的方便我们去观察几个修饰符的作用
<template>
<div>
<div class="bigdiv" @click="bigclick">
<div class="smalldiv" @click="smallclick"></div>
</div>
<a href="https://www.baidu.com" @click="aclick">百度的链接</a>
</div>
</template>
<script>
export default {
methods: {
bigclick() {
alert("bigclick被触发了");
},
smallclick() {
alert("smallclick被触发了");
},
aclick() {
alert("点击了a标签");
}
}
};
</script>
<style scoped>
.bigdiv {
width: 200px;
height: 200px;
background-color: green;
}
.smalldiv {
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
页面点击会发生啥,事件冒泡还有事件捕获啥的,我就不详细说了
简单的介绍下怎么去使用几个修饰符,
stop
prevent
capture
self
once
passive
.stop
作用:阻止事件冒泡
<template>
<div>
<div class="bigdiv" @click="bigclick">
<div class="smalldiv" @click.stop="smallclick"></div>
</div>
<a href="https://www.baidu.com" @click="aclick">百度的链接</a>
</div>
</template>
<script>
export default {
methods: {
bigclick() {
alert("bigclick被触发了");
},
smallclick() {
alert("smallclick被触发了");
},
aclick() {
alert("点击了a标签");
}
}
};
</script>
<style scoped>
.bigdiv {
width: 200px;
height: 200px;
background-color: green;
}
.smalldiv {
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
将stop修饰符添在小div的内部,这样当小的div触发点击事件的时候,大的div就不会触发(阻止事件冒泡)
效果
页面点击黄色的div时候,不会弹出绿色div的弹窗
.prevent
作用:阻止默认事件的触发
<template>
<div>
<div class="bigdiv" @click="bigclick">
<div class="smalldiv" @click.stop="smallclick"></div>
</div>
<a href="https://www.baidu.com" @click.prevent="aclick">百度的链接</a>
</div>
</template>
<script>
export default {
methods: {
bigclick() {
alert("bigclick被触发了");
},
smallclick() {
alert("smallclick被触发了");
},
aclick() {
alert("点击了a标签");
}
}
};
</script>
<style scoped>
.bigdiv {
width: 200px;
height: 200px;
background-color: green;
}
.smalldiv {
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
给a标签的点击事件添加上.prevent的时候,原本点击a标签,会跳转到百度上去,但是现在就只会弹窗,并且不会跳转到页面。阻止了它的默认行为
效果
页面点击‘百度’这一个链接的时候,页面不会跳转,直接弹窗
.once
作用:使得元素的事件只触发一次
<template>
<div>
<div class="bigdiv" @click.once="bigclick">
<div class="smalldiv" @click.stop="smallclick"></div>
</div>
<a href="https://www.baidu.com" @click.prevent="aclick">百度的链接</a>
</div>
</template>
<script>
export default {
methods: {
bigclick() {
alert("bigclick被触发了");
},
smallclick() {
alert("smallclick被触发了");
},
aclick() {
alert("点击了a标签");
}
}
};
</script>
<style scoped>
.bigdiv {
width: 200px;
height: 200px;
background-color: green;
}
.smalldiv {
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
给bigdiv的点击事件添加上.once,当点击bigdiv的时候,第一次会弹窗,但是后面再次点击的时候就不会有弹窗出来了
效果
点击绿色的div,只有第一次会出现弹窗
.capture
作用:当元素的冒泡发生的时候,优先执行添加了capture的事件(下方代码进行了修改,添加了一个class名为middlediv的蓝色div)
<template>
<div>
<div class="bigdiv" @click.capture="bigclick">
<div class="middlediv" @click="middleclick">
<div class="smalldiv" @click="smallclick"></div>
</div>
</div>
<a href="https://www.baidu.com" @click.prevent="aclick">百度的链接</a>
</div>
</template>
<script>
export default {
methods: {
bigclick() {
alert("bigclick被触发了");
},
smallclick() {
alert("smallclick被触发了");
},
aclick() {
alert("点击了a标签");
}
}
};
</script>
<style scoped>
.bigdiv {
width: 200px;
height: 200px;
background-color: green;
}
.middlediv {
width: 150px;
height: 150px;
background-color: blue;
}
.smalldiv {
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
给middlediv的点击事件添加了capture修饰符之后,middlediv的事件会优先触发,然后再按照自然顺序,先触发small的,再出发big的
效果
点击黄色的div,优先出现的弹窗是‘middleclick被触发了’
备注
试试看如果给middlediv的点击事件添加个stop,即
<div class="middlediv" @click.capture.stop="middleclick">
看看会怎么样
.self
作用:只有点击元素本身的时候,才会触发这个元素的事件
<template>
<div>
<div class="bigdiv" @click="bigclick">
<div class="middlediv" @click.self="middleclick">
<div class="smalldiv" @click="smallclick"></div>
</div>
</div>
<a href="https://www.baidu.com" @click.prevent="aclick">百度的链接</a>
</div>
</template>
<script>
export default {
methods: {
bigclick() {
alert("bigclick被触发了");
},
smallclick() {
alert("smallclick被触发了");
},
middleclick() {
alert("middleclick被触发了");
},
aclick() {
alert("点击了a标签");
}
}
};
</script>
<style scoped>
.bigdiv {
width: 200px;
height: 200px;
background-color: green;
}
.middlediv {
width: 150px;
height: 150px;
background-color: blue;
}
.smalldiv {
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
给middlediv的点击事件添加了.self的时候,只有middlediv本身被点击的时候,才会触发middlediv的事件
效果
点击黄色div的时候,没有触发蓝色div的点击事件,只有点击蓝色模块的时候,才会触发蓝色模块的点击事件
.passive
passive的描述比较麻烦,我就扯一些别的吧
这儿讲到了一点addEventListener事件,那么我们就看下这个事件里面的passiver是啥
大概明白了,作用就是改善滚动事件,更多详细,请查看下方关于mdn的链接(搬太多砖容易让大家曲解,原文档我就觉得讲的很好)