在事件处理程序中调用 event.preventDefault()
或 event.stopPropagation()
是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 v-on
提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。
.stop
.prevent
.capture
.self
.once
<!-- 阻止单击事件继续传播 --> <a v-on:click.stop="doThis"></a> <!-- 提交事件不再重载页面 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 修饰符可以串联 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 只有修饰符 --> <form v-on:submit.prevent></form> <!-- 添加事件监听器时使用事件捕获模式 --> <!-- 即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理 --> <div v-on:click.capture="doThis">...</div> <!-- 只当在 event.target 是当前元素自身时触发处理函数 --> <!-- 即事件不是从内部元素触发的 --> <div v-on:click.self="doThat">...</div>
1.阻止事件冒泡 .stop
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Vue阻止事件冒泡</title> 5 <script src="https://cdn.jsdelivr.net/npm/vue"></script> 6 <style type="text/css"> 7 div{ 8 width:100px; 9 height:100px; 10 border:1px solid orange; 11 } 12 </style> 13 </head> 14 <body> 15 <div @click='parentClick'> 16 <button @click.stop='childClick'>点击按钮</button> 17 </div> 18 <script type="text/javascript"> 19 var app = new Vue({ 20 el:'div', 21 methods:{ 22 parentClick:function(){ 23 alert('parent click!'); 24 }, 25 childClick:function(){ 26 alert('child click!') 27 } 28 } 29 }) 30 </script> 31 </body> 32 </html>
2.阻止默认行为 .prevent
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <title>Vue阻止事件默认行为,但不会阻止冒泡</title> 6 <script src="https://cdn.jsdelivr.net/npm/vue"></script> 7 </head> 8 <body> 9 <div> 10 <input type="checkbox" @click.prevent>复选框 11 </div> 12 <script type="text/javascript"> 13 var app = new Vue({ 14 el:'div' 15 }) 16 </script> 17 </body> 18 </html>
3.添加事件监听器时使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理 .capture
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>.capture事件修饰符-捕获模式</title> 6 <style type="text/css"> 7 * { 8 margin: 0 auto; 9 text-align:center; 10 line-height: 40px; 11 } 12 div { 13 width: 100px; 14 } 15 #obj1 { 16 background: deeppink; 17 } 18 #obj2 { 19 background: pink; 20 } 21 #obj3 { 22 background: hotpink; 23 }#obj4 { 24 background: #ff4225; 25 } 26 </style> 27 <script src="https://cdn.jsdelivr.net/npm/vue"></script> 28 </head> 29 <body> 30 <div id="content"> 31 <div id="obj1" v-on:click.capture="doc"> 32 obj1 33 <div id="obj2" v-on:click.capture="doc"> 34 obj2 35 <div id="obj3" v-on:click="doc"> 36 obj3 37 <div id="obj4" v-on:click="doc"> 38 obj4 39 <!--点击obj4的时候,弹出的顺序为:obj1、obj2、obj4、obj3; 40 由于1,2有修饰符,故而先触发事件,然后就是4本身触发,最后冒泡事件。 41 --> 42 </div> 43 </div> 44 </div> 45 </div> 46 47 </div> 48 <script type="text/javascript"> 49 var content = new Vue({ 50 el: "#content", 51 data: { 52 id: '' 53 }, 54 methods: { 55 doc: function () { 56 this.id= event.currentTarget.id; 57 alert(this.id) 58 } 59 } 60 }) 61 </script> 62 </body> 63 </html>
点击obj4的时候,弹出的顺序为:obj1,obj2,obj4,obj3,因为1,2有修饰符故而先事发1,2的点击事件,然后触发自身的事件,obj3的事件是由事件冒泡导致的.
4.内部子元素的事件冒泡不会触发该函数,只有自身的事件可以触发该函数的调用.self
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>vue-.self</title> 5 <script src="https://cdn.jsdelivr.net/npm/vue"></script> 6 </head> 7 <style type="text/css"> 8 div{ 9 width: 100px; 10 height: 100px; 11 border: 1px solid orange; 12 } 13 </style> 14 <body> 15 <div @click.self='parentClick'> 16 <button @click='childClick'>按钮</button> 17 </div> 18 <script type="text/javascript"> 19 var app = new Vue({ 20 el:'div', 21 methods:{ 22 parentClick:function(){ 23 alert('parent Click!'); 24 }, 25 childClick:function(){ 26 alert('child Click!'); 27 } 28 } 29 }) 30 </script> 31 </body> 32 </html>
上述代码中,点击button不会触发parentClick,原因是parentCilck的事件绑定中有修饰符self,只有自身点击才会触发parentClick.