重新认识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 相关文章推荐
javascript静态的url如何传递
May 03 Javascript
jQuery live( type, fn ) 委派事件实现
Oct 11 Javascript
IE bug table元素的innerHTML
Jan 11 Javascript
jquery 页面全选框实践代码
Apr 02 Javascript
用C/C++来实现 Node.js 的模块(一)
Sep 24 Javascript
JavaScript精炼之构造函数 Constructor及Constructor属性详解
Nov 05 Javascript
全面解析标签页的切换方式
Aug 21 Javascript
vue-router重定向不刷新问题的解决
Jun 25 Javascript
vuex提交state&amp;&amp;实时监听state数据的改变方法
Sep 16 Javascript
vue axios 简单封装以及思考
Oct 09 Javascript
js前端面试之同步与异步问题详解
Apr 03 Javascript
原生js拖拽实现图形伸缩效果
Feb 10 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 程式大小
2006/12/06 PHP
实测在class的function中include的文件中非php的global全局环境
2013/07/15 PHP
php cli换行示例
2014/04/22 PHP
PHP中exec函数和shell_exec函数的区别
2014/08/20 PHP
Zend Framework教程之请求对象的封装Zend_Controller_Request实例详解
2016/03/07 PHP
Yii2实现同时搜索多个字段的方法
2016/08/10 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
2018/02/23 PHP
PHP使用ajax的post方式下载excel文件简单示例
2019/08/06 PHP
游戏人文件夹程序 ver 4.03
2006/07/14 Javascript
Javascript的一种模块模式
2008/03/22 Javascript
简略的前端架构心得&amp;&amp;基于editor为例子的编码小技巧
2010/11/25 Javascript
jquery图片放大功能简单实现
2013/08/01 Javascript
jquery easyui滚动条部分设置介绍
2013/09/12 Javascript
js如何取消事件冒泡
2013/09/23 Javascript
js 显示base64编码的二进制流网页图片
2014/04/04 Javascript
jquery的trigger和triggerHandler的区别示例介绍
2014/04/20 Javascript
常用jQuery代码分享
2015/07/14 Javascript
JS+CSS实现大气的黑色首页导航菜单效果代码
2015/09/10 Javascript
AngularJS实现的2048小游戏功能【附源码下载】
2018/01/03 Javascript
layui数据表格重载实现往后台传参
2019/11/15 Javascript
JS实现简易计算器
2020/02/14 Javascript
Python动态加载模块的3种方法
2014/11/22 Python
python 实时遍历日志文件
2016/04/12 Python
Python实现批量更换指定目录下文件扩展名的方法
2016/09/19 Python
django创建自定义模板处理器的实例详解
2017/08/14 Python
Python实现我的世界小游戏源代码
2021/03/02 Python
特罗佩亚包官方网站:Tropea
2017/01/03 全球购物
Reformation官网:美国女装品牌
2018/09/14 全球购物
什么是JNDI的上下文?如何初始化JNDI上下文
2012/03/10 面试题
高中运动会入场词
2014/02/14 职场文书
2014年国培研修感言
2014/03/09 职场文书
政风行风建设责任书
2014/07/23 职场文书
2015年幼儿园班务工作总结
2015/05/12 职场文书
导游词之湖北梁子湖
2019/11/07 职场文书
详解Spring Security中的HttpBasic登录验证模式
2022/03/17 Java/Android
CentOS7设置ssh服务以及端口修改方式
2022/12/24 Servers