熟悉了 Vue 的指令系统后,在实际开发中,不可避免的会使用到对于事件的操做,如何处理 DOM 事件流,成为咱们必需要掌握的技能。不一样于传统的前端开发,在 Vue 中给咱们提供了事件修饰符这一利器,使咱们能够便捷的处理 DOM 事件,本章,一块儿来学习如何使用事件修饰符来实现对于 DOM 事件流的操做。html
仓储地址:Chapter01-Rookie Event Modifiers前端
1、 DOM 事件流vue
有时,当咱们须要完成页面中的某些功能时,咱们要在须要实现功能的页面元素上使用 v-on 指令去监听 DOM 事件,在 html4 时代浏览器如何肯定页面的哪一部分会拥有特定的事件时,IE 和 Netscape 的开发团队提出了两个截然相反的概念。这一差别,也使咱们在写代码中须要考虑如何去处理 DOM 的事件细节。为了解决这一问题,vue 给咱们提供了事件修饰符这一利器,它使咱们的方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。git
一些涉及到概念:程序员
一、事件:用户设定或者是浏览器自身执行的某种动做。例如click(点击)、load(加载)、mouseover(鼠标悬停)、change(改变)等等github
二、事件处理程序:为了实现某个事件的功能而构建的函数方法,也可称为事件监听器编程
三、DOM事件流:描述的是从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序segmentfault
在DOM事件流中存在着三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段浏览器
事件捕获(event capture):当鼠标点击或者触发DOM事件时,浏览器会从根节点开始由外到内进行事件传播,即点击了子元素,若是父元素经过事件捕获方式注册了对应的事件的话,会先触发父元素绑定的事件app
事件冒泡(event bubbing):当鼠标点击或者触发DOM事件时,浏览器会从根节点开始由内到外进行事件传播,即点击了子元素,则先触发子元素绑定的事件,逐步扩散到父元素绑定的事件
以前咱们提到的 IE 和 Netscape 的开发团队提出了两个截然相反的事件流概念,IE 采起的是事件冒泡流,而标准的浏览器的事件流则是事件捕获流。因此,为了兼容 IE 咱们须要改变某些的写法。
2、 事件修饰符
一、.stop:阻止事件冒泡
在下面的示例中,咱们分别建立了一个 button 的点击事件和外侧的 div 的点击事件,根据事件的冒泡机制咱们能够得知,当咱们点击了按钮以后,会扩散到父元素,从而触发父元素的点击事件,具体的结果也以下图所示:
<div id="app" class="divDefault">
<div id="div1" @click="divHandlerClick">
<input type="button" value="点击" @click="btnHandlerClick" />
</div>
</div>
<script> var vm = new Vue({ el: '#app', data: {}, methods: { divHandlerClick() { alert('我是div的点击事件!') }, btnHandlerClick() { alert('我是button的点击事件') } } }); </script>
复制代码
<input type="button" value="点击" @click.stop="btnHandlerClick" />
复制代码
阻止默认事件这个也很好理解,有些标签自己会存在事件,例如,a 标签的跳转,form 表单中 submit 按钮的提交事件等等,在某些时候咱们只想执行咱们本身设置的事件,这时,就须要阻止标签的默认事件的执行,原生的 js 咱们可使用 preventDefault 方法来实现,而在 Vue 中,咱们只须要使用 prevent 关键字就能够了。
在下面的示例中,咱们为 a 标签添加了一个点击事件,因为 a 标签自己具备默认的跳转事件,此时,当咱们点击后,最终仍是会执行 a 标签的默认事件。
<a href="http://www.baidu.com" @click="aHandlerClick">连接跳转</a>
<script> var vm = new Vue({ el: '#app', data: {}, methods: { aHandlerClick() { alert('我是a标签的点击事件') } } }); </script>
复制代码
<a href="http://www.baidu.com" @click.prevent="aHandlerClick">连接跳转</a>
复制代码
在上面的学习中咱们了解到,事件捕获模式与事件冒泡模式是一对相反的事件处理流程,当咱们想要将页面元素的事件流改成事件捕获模式时,只须要在父级元素的事件上使用 capture 修饰符便可,仍是上面的例子的代码,当咱们在 div 绑定的点击事件上使用 capture 修饰符后,咱们点击按钮首先触发的就是最外侧的 div 的事件。
<div id="app" class="divDefault">
<div id="div1" @click.capure="divHandlerClick">
<input type="button" value="点击" @click="btnHandlerClick" />
</div>
</div>
复制代码
在上面的例子中,咱们为 div 绑定了一个点击事件,而咱们的本意多是只有当咱们点击 div 后触发这个事件,而实际状况是事件冒泡仍是事件捕获都会触发这个事件,这与咱们的本意是不符的。在 Vue 中,咱们就可使用 self 修饰符去修饰事件,让这个事件只在咱们想要触发时触发。
<div id="app" class="divDefault">
<div id="div1" @click.self="divHandlerClick">
<input type="button" value="点击" @click="btnHandlerClick" />
</div>
</div>
复制代码
当咱们仅仅想对绑定的事件只在第一次的时候触发,这时咱们就可使用 once 修饰符去修饰绑定的事件。例如在下面的代码中,只有第一次点击时才会触发绑定的事件,以后点击都不会触发。
<input type="button" value="点击" @click.once="btnHandlerClick" />
复制代码
在页面滚动的时候,浏览器会在整个事件处理完毕以后再触发滚动,由于浏览器并不知道这个事件是否在其处理函数中被调用了 event.preventDefault(),而 passive 修饰符用来进一步告诉浏览器这个事件的默认行为不会被取消,即 使用 passive 修饰符后表示绑定的事件永远不会调用 event.preventDefault()。
一、使用修饰符时,顺序很重要;相应的代码会以一样的顺序产生。所以,用 v-on:click.prevent.self会阻止全部的点击,而v-on:click.self.prevent 只会阻止对元素自身的点击。
二、不要把 .passive 和 .prevent 一块儿使用,由于 .prevent 将会被忽略,同时浏览器可能会向你展现一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。
四、JavaScript 详说事件机制之冒泡、捕获、传播、委托
占坑
做者:墨墨墨墨小宇
我的简介:96年生人,出生于安徽某四线城市,毕业于Top 10000000 院校。.NET程序员,枪手死忠,喵星人。于2016年12月开始.NET程序员生涯,微软.NET技术的坚决坚持者,立志成为云养猫的少年中面向谷歌编程最厉害的.NET程序员。
我的博客:yuiter.com
博客园博客:www.cnblogs.com/danvic712