8、事件修饰符
目标:
1、掌握四个事件修饰符,它们分别是 stop / prevent / self / once ;
2、搞清楚 stop修饰符 与 self修饰符 之间的区别 。
一、stop
作用:阻止事件冒泡。
<style>
.box {
width: 100px;
height: 100px;
border: 1px solid red;
</style>
<div id="app">
<div @click="boxClick" class="box"> // 1、div 父元素
<button @click="btnClick">click me</button> // 2、button 子元素
var app = new Vue({
el: '#app',
data: {
methods: {
boxClick() { // 3、父元素的单击事件
console.log('box click')
btnClick() { // 4、子元素的单击事件
console.log('btn click')
})
上面代码中,定义了 div 父元素 和 button 子元素,并分别给他们添加了单击事件。
- 当点击 div 时(不点击 button ),控制台会打印出 "box click" ;
- 当点击 button 时,控制台会打印出 "btn click" 和 "button click" 。
这是因为,button 作为 div 的子元素,当点击 子元素button 时,button 的单击事件会冒泡到 父元素div ,从而触发 div 的 click 事件。所以会先执行 button 的 click 事件,再执行 div 的 click 事件。
然而很多时候,我们是不希望事件会往上冒泡的。比如上面的例子,我们只希望 button 的 click 事件被触发,不希望 div 的 click 事件被触发。
针对这个问题,Vue 中的 stop 修饰符就派上了用场,它会阻止事件的冒泡。
你只需要在 button 的 click 事件后面加上 ".stop",如:
<button @click.stop="btnClick">click me</button>
注意:修饰符以 点 开头。
这样一来,button 的 click 事件就不会向上冒泡,div 的 click 事件也就不会被触发。
二、prevent
作用:提交事件,并且不重载页面。
<div id="app">
<form action="" @submit="handle"> // 1、一个表单,并且定义了 submit 事件
<button type="submit">提交</button> // 2、当点击按钮时,表单就会被提交
</form>
var app = new Vue({
el: '#app',
data: {
methods: {
handle() {
console.log('表单被提交了') // 3、表单提交后,打印文本
})
上面代码中,当点击表单中的提交按钮后,表单就会被提交,控制台会打印文本,并且页面会被刷新。需要注意的是, submit 事件应该定义在 form 元素上,而不是 button 元素上。
然而页面被刷新这件事,明显不利于用户体验,所以很多时候,会有提交表单时阻止页面刷新的需求。
在 Vue 中,要做到这件事很简单,只需要用到 prevent 修饰符即可:
<form action="" @submit.prevent="handle"> // 在 submit 事件后加上 .prevent
<button type="submit">提交</button>
</form>
此时,表单仍然会被提交,控制台仍然会打印文本,但是页面不再刷新。
三、self
作用:只有当前元素自身才能触发,当前元素的子元素不能触发。
以上面事件冒泡的代码为例:
<style>
.box {
width: 100px;
height: 100px;
border: 1px solid red;
</style>
<div id="app">
<div @click="boxClick" class="box"> // 1、div 父元素
<button @click="btnClick">click me</button> // 2、button 子元素
var app = new Vue({
el: '#app',
data: {
methods: {
boxClick() { // 3、父元素的单击事件
console.log('box click')
btnClick() { // 4、子元素的单击事件
console.log('btn click')
})
上面代码中,定义了 div 父元素 和 button 子元素,并分别给他们添加了单击事件。
- 当点击 div 时(不点击 button ),控制台会打印出 "box click" ;
- 当点击 button 时,控制台会打印出 "btn click" 和 "button click" 。
原因不再赘述。
这里需要注意的是,父元素div 的 click 事件,并不是只有 div 自己能触发,div 的子元素 button 也可以通过冒泡触发 div 的 click 事件。
而我们不希望 button 触发 div 的 click 事件,只希望 div 自己触发自己的 click 事件。
解决办法:
如上面说到的,你可以给 子元素button 加 stop 修饰符,阻止 button 的 click 事件向上冒泡,实现不触发 父元素div 的 click 事件的目的。
但是我们都知道,父元素div 可能会有很多个子元素,如果其他子元素也有 click 事件,那么就要给所有子元素加上 stop 修饰符,这未免有点麻烦。
所以,我们希望,所有子元素都不要触发父元素的 click 事件,只让父元素自己触发自己的 click 事件。(猴子猴孙快闪开,让俺老孙来对付他们,dai,妖怪,哪里跑~~)
所以我们只需要给父元素加上 self 修饰符即可,如:
<div @click.self="boxClick" class="box">
<button @click="btnClick">click me</button>
</div>
此时,点击 div 元素(不点击 button),会触发 click 事件,点击 button ,不会触发父元素的 click 事件。
ps:其实我用的也不多,不敢说了解。但是我还是发表一下我的愚见,供同学们参考。
self 修饰符 与 stop 修饰符 可能会让你有点混淆不清,你需要再细细品味它们之间的区别:
- stop 是写在子元素上的,而 self 是写在父元素上的;
- stop 是为了阻止子元素的事件向父元素冒泡,self 是为了不让子元素触发我(父元素)的事件。
四、once
作用:让事件只触发一次。
<div id="app">
<button @click.once="once">once</button> // 1、这个 button 只能点一次
<button @click="more">more</button> // 2、这个 button 可以点多次
var app = new Vue({
el: '#app',
data: {
methods: {
once() {
console.log('只执行一次')