重新认识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 的 trim 函数的代码
Aug 13 Javascript
浅谈JavaScript函数参数的可修改性问题
Dec 05 Javascript
关于onchange事件在IE和FF下的表现及解决方法
Mar 08 Javascript
Bootstrap栅格系统的使用和理解2
Dec 14 Javascript
EditPlus 正则表达式 实战(3)
Dec 15 Javascript
jQuery基于ajax操作json数据简单示例
Jan 05 Javascript
详解使用webpack打包编写一个vue-toast插件
Nov 08 Javascript
详解从零搭建 vue2 vue-router2 webpack3 工程
Nov 22 Javascript
Vim快速合并行及vim 将文件所有行合并到一行
Nov 27 Javascript
解决Vue.js 2.0 有时双向绑定img src属性失败的问题
Mar 14 Javascript
Node.js Stream ondata触发时机与顺序的探索
Mar 08 Javascript
微信小程序中的video视频实现 自定义播放按钮、封面图、视频封面上文案
Jan 02 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
多文件上传的例子
2006/10/09 PHP
PHP对接微信公众平台消息接口开发流程教程
2014/03/25 PHP
PHP程序员的技术成长规划
2016/03/25 PHP
php获取服务器操作系统相关信息的方法
2016/10/08 PHP
浅析PHP中的 inet_pton 网络函数
2019/12/16 PHP
Prototype源码浅析 Enumerable部分(二)
2012/01/18 Javascript
在浏览器窗口上添加遮罩层的方法
2012/11/12 Javascript
js 数值转换为3位逗号分隔的示例代码
2014/02/19 Javascript
利用jquery动画特效和css打造的侧边弹出垂直导航
2014/04/04 Javascript
深入理解JavaScript系列(37):设计模式之享元模式详解
2015/03/04 Javascript
Bootstrap源码解读导航(6)
2016/12/23 Javascript
JavaScript实现修改伪类样式
2017/11/27 Javascript
vue实现组件之间传值功能示例
2018/07/13 Javascript
vue-cli脚手架build目录下utils.js工具配置文件详解
2018/09/14 Javascript
vue v-for循环重复数据无法添加问题解决方法【加track-by='索引'】
2019/03/15 Javascript
vue-cli点击实现全屏功能
2020/03/07 Javascript
JavaScript日期库date-fn.js使用方法解析
2020/09/09 Javascript
基于element-ui对话框el-dialog初始化的校验问题解决
2020/09/11 Javascript
详解Python中的相对导入和绝对导入
2017/01/06 Python
python3+PyQt5+Qt Designer实现扩展对话框
2018/04/20 Python
Django 忘记管理员或忘记管理员密码 重设登录密码的方法
2018/05/30 Python
Python中的Numpy矩阵操作
2018/08/12 Python
Python Numpy中数据的常用保存与读取方法
2020/04/01 Python
CSS3 Flex 弹性布局实例代码详解
2018/11/01 HTML / CSS
Html5写一个简单的俄罗斯方块小游戏
2019/12/03 HTML / CSS
英国第一豪华护肤品牌:Elemis
2017/10/12 全球购物
西班牙英格列斯百货英国官网:El Corte Inglés英国
2017/10/30 全球购物
爱尔兰橄榄球店:Irish Rugby Store
2019/12/05 全球购物
香奈儿美国官网:CHANEL美国
2020/05/20 全球购物
高中生第一学年自我鉴定2015
2014/09/28 职场文书
学校政风行风评议心得体会
2014/10/21 职场文书
毕业论文致谢范文
2015/05/14 职场文书
考生诚信考试承诺书(2016版)
2016/03/25 职场文书
分析Netty直接内存原理及应用
2021/06/14 Java/Android
Vue自定义铃声提示音组件的实现
2022/01/22 Vue.js
使用Django框架创建项目
2022/06/10 Python