重新认识vue之事件阻止冒泡的实现


Posted in Javascript onAugust 02, 2018

冒泡的表现

近期用vue做了一个需求,大概是同一个区域,点击不同位置有不同的响应函数,还有个总的响应函数,好吧,如下图所示:

重新认识vue之事件阻止冒泡的实现

他们的DOM结构如下:

<div v-for="(item, index) in listData" @click="handleClick3">
  <el-col :span="grid">
    <div @click="handleClick1"></div>
  </el-col>
  <el-col @click="handleClick2">
  </el-col>
</div>

冒泡在这里的表现就是当用户点击图中事件1或事件2区域时,事件3也会执行。这是因为时间冒泡机制,导致点击'handleClick1'时'handleClick3' 也会响应。在大部分的时候这都是不希望的, 同样我这里也不希望。

看下冒泡的经典描述吧还是

重新认识vue之事件阻止冒泡的实现

图中4,5,6,7步骤就是冒泡阶段。

通用解决办法

事件冒泡了嘛,那就阻止事件冒泡呗。 鉴于不同浏览器阻止事件冒泡方法不一样,建议手写一个事件阻止冒泡方法.

function stopPropagation(event){
  var e=arguments.callee.caller.arguments[0] || event;//这里是因为除了IE有event其他浏览器没有所以要做兼容
  if(window.event){    //这是IE浏览器
    e.cancelBubble=true;
  }else if(e && e.stopPropagation){   //这是其他浏览器
    e.stopPropagation();//阻止冒泡事件
  }
}

<button onclick="stopPropagation(event)"> 按钮 </button>  // 使用

vue中解决办法

上述兼容方法,针对 event 和 停止冒泡方法均做了兼容。 但是在vue中需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法。如:

<button v-on:click="warn('Form cannot be submitted yet.', $event)">
 Submit
</button>

// ...
methods: {
 warn: function (message, event) {
  // 现在我们可以访问原生事件对象
  if (event) event.preventDefault()
  alert(message)
 }
}

因此这里我们可以简化一下上述停止冒泡方法:

function stopPropagation(event) {
  if(event) {
    event.stopPropagation ? event.stopPropagation(): event.cancelBubble = true;
  }
}

evnet 为 $event

vue中处理冒泡标准姿势

事件修饰符

Vue.js 为 v-on 提供了事件修饰符,修饰符是由点开头的指令后缀来表示的。这些事件修饰符主要有以下几个:

  1. stop
  2. prevent
  3. capture
  4. prevent
  5. self
  6. once
  7. passive

看到没有,第一个'stop'就是我们想要的!

这些修饰符正是为了解决这些问题而生的。也就说我们只需要在模板中这样写就搞定停止冒泡了。

<div v-for="(item, index) in listData" @click="handleClick3">
  <el-col :span="grid">
    <div @click.stop="handleClick1"></div>
  </el-col>
  <el-col @click.stop="handleClick2">
  </el-col>
</div>

很完美有没有,这就不用在事件响应逻辑中去处理dom事件细节了。

除 冒泡之外,vue提供的修饰符还有这些功能。

<!-- 阻止单击事件继续传播 -->
<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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Extjs中DisplayField的日期或者数字格式化扩展
Sep 03 Javascript
复制小说文本时出现的随机乱码的去除方法
Sep 07 Javascript
只需20行代码就可以写出CSS覆盖率测试脚本
Apr 24 Javascript
jquery对table中各数据的增加、保存、删除操作示例
May 14 Javascript
javascript为下拉列表动态添加数据项
May 23 Javascript
jquery用offset()方法获得元素的xy坐标
Sep 06 Javascript
js获取元素相对窗口位置的实现代码
Sep 28 Javascript
node.js中的fs.utimesSync方法使用说明
Dec 15 Javascript
jquery简单插件制作(fn.extend)完整实例
May 24 Javascript
移动端日期插件Mobiscroll.js使用详解
Dec 19 Javascript
Element-UI+Vue模式使用总结
Jan 02 Javascript
在Vue中实现随hash改变响应菜单高亮
Mar 09 Javascript
深入浅出理解JavaScript高级定时器原理与用法
Aug 02 #Javascript
解决vue router组件状态刷新消失的问题
Aug 01 #Javascript
Promise.all中对于reject的处理方法
Aug 01 #Javascript
详解es6超好用的语法糖Decorator
Aug 01 #Javascript
Vue Router去掉url中默认的锚点#
Aug 01 #Javascript
vue定义全局变量和全局方法的方法示例
Aug 01 #Javascript
node.js遍历目录的方法示例
Aug 01 #Javascript
You might like
德劲1103的维修打理经验
2021/03/02 无线电
ThinkPHP连接数据库的方式汇总
2014/12/05 PHP
php超快高效率统计大文件行数
2015/07/05 PHP
PHP面向对象程序设计之对象生成方法详解
2016/12/02 PHP
php 静态属性和静态方法区别详解
2017/04/09 PHP
js url传值中文乱码之解决之道
2009/11/20 Javascript
Jquery iframe内部出滚动条
2010/02/11 Javascript
jquery 操作表格实现代码(多种操作打包)
2011/03/20 Javascript
js给dropdownlist添加选项的小例子
2013/03/04 Javascript
JS实现拖动示例代码
2013/11/01 Javascript
理解JS绑定事件
2016/01/19 Javascript
实例解析jQuery中proxy()函数的用法
2016/05/24 Javascript
JavaScript进阶练习及简单实例分析
2016/06/03 Javascript
Vue自定义指令拖拽功能示例
2017/02/17 Javascript
详解vue-meta如何让你更优雅的管理头部标签
2018/01/18 Javascript
NodeJS搭建HTTP服务器的实现步骤
2018/10/12 NodeJs
JS实现可以用键盘方向键控制的动画
2020/12/11 Javascript
Vue-router中hash模式与history模式的区别详解
2020/12/15 Vue.js
[01:11:21]DOTA2-DPC中国联赛 正赛 VG vs Elephant BO3 第一场 3月6日
2021/03/11 DOTA
Python通过poll实现异步IO的方法
2015/06/04 Python
Python内置模块turtle绘图详解
2017/12/09 Python
python把数组中的数字每行打印3个并保存在文档中的方法
2018/07/17 Python
python实现换位加密算法的示例
2018/10/14 Python
浅谈Pandas:Series和DataFrame间的算术元素
2018/12/22 Python
python使用xlrd模块读取xlsx文件中的ip方法
2019/01/11 Python
Python队列RabbitMQ 使用方法实例记录
2019/08/05 Python
Pandas数据离散化原理及实例解析
2019/11/16 Python
django rest framework serializers序列化实例
2020/05/13 Python
Python与C/C++的相互调用案例
2021/03/04 Python
俄罗斯领先的移动和数字设备在线商店:Svyaznoy.ru
2020/12/21 全球购物
什么是.net的Remoting技术
2016/07/08 面试题
60条职场经典语录,总有一条能触动你的心
2019/08/21 职场文书
浅谈CSS不规则边框的生成方案
2021/05/25 HTML / CSS
pycharm部署django项目到云服务器的详细流程
2021/06/29 Python
java设计模式--原型模式详解
2021/07/21 Java/Android
解决Redis启动警告问题
2022/02/24 Redis