重新认识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 相关文章推荐
基于jQuery UI CSS Framework开发Widget的经验
Aug 21 Javascript
Javascript基础知识(二)事件
Sep 29 Javascript
JavaScript获得url查询参数的方法
Jul 02 Javascript
JavaScript性能优化之小知识总结
Nov 20 Javascript
js获取及修改网页背景色和字体色的方法
Dec 29 Javascript
Centos7 中 Node.js安装简单方法
Nov 02 Javascript
JavaScript获取中英文混合字符串长度的方法示例
Feb 04 Javascript
js for循环倒序输出数组元素的实例
Mar 01 Javascript
vue使用$emit时,父组件无法监听到子组件的事件实例
Feb 26 Javascript
vue富文本编辑器组件vue-quill-edit使用教程
Sep 21 Javascript
Vue源码探究之虚拟节点的实现
Apr 17 Javascript
layui 实现表单和文件上传一起传到后台的例子
Sep 16 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
PHP nl2br函数 将换行字符转成 &amp;lt;br&amp;gt;
2009/08/21 PHP
php实现网站顶踩功能的完整前端代码
2015/07/19 PHP
CI框架的安全性分析
2016/05/18 PHP
基于iframe实现类似于ajax的页面无刷新
2014/05/31 Javascript
简单易用的倒计时js代码
2014/08/04 Javascript
JavaScript判断浏览器类型的方法
2015/02/10 Javascript
浅谈JavaScript中运算符的优先级
2015/07/07 Javascript
JavaScript代码实现图片循环滚动效果
2020/03/19 Javascript
详谈js中window.location.search的用法和作用
2017/02/13 Javascript
js学习总结之DOM2兼容处理重复问题的解决方法
2017/07/27 Javascript
js禁止Backspace键使浏览器后退的实现方法
2017/09/01 Javascript
微信小程序实现天气预报功能
2018/07/18 Javascript
vue中slot(插槽)的介绍与使用
2018/11/12 Javascript
layui问题之自动滚动二级iframe页面到指定位置的方法
2019/09/18 Javascript
8个非常实用的Vue自定义指令
2020/12/15 Vue.js
[01:03:13]VG vs Pain 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python程序设计入门(5)类的使用简介
2014/06/16 Python
python学习 流程控制语句详解
2016/06/01 Python
python实现windows下文件备份脚本
2018/05/27 Python
对python 操作solr索引数据的实例详解
2018/12/07 Python
python中下标和切片的使用方法解析
2019/08/27 Python
python进程池实现的多进程文件夹copy器完整示例
2019/11/27 Python
基于Django集成CAS实现流程详解
2020/11/28 Python
HTML5全屏(Fullscreen)API详细介绍
2015/04/24 HTML / CSS
Myprotein丹麦官网:欧洲第一运动营养品牌
2019/04/15 全球购物
中国央视网签名寄语
2014/01/18 职场文书
中秋寄语大全
2014/04/11 职场文书
教师考核评语大全
2014/12/31 职场文书
2015年小学校长工作总结
2015/05/19 职场文书
民事答辩状范本
2015/05/21 职场文书
2016读书月活动心得体会
2016/01/14 职场文书
2016年企业先进员工事迹材料
2016/02/25 职场文书
《哪吒之魔童降世》观后感:世上哪有随随便便的成功
2019/11/08 职场文书
redis客户端实现高可用读写分离的方式详解
2021/07/04 Redis
Vue的列表之渲染,排序,过滤详解
2022/02/24 Vue.js
基于Redission的分布式锁实战
2022/08/14 Redis