重新认识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 相关文章推荐
js实现简单的星级选择器提交效果适用于评论等
Oct 18 Javascript
对Jquery中的ajax再封装,简化操作示例
Feb 12 Javascript
理解JS事件循环
Jan 07 Javascript
js 获取站点应用名的简单实例
Aug 18 Javascript
Vue.js动态添加、删除选题的实例代码
Sep 30 Javascript
Bootstrap CSS使用方法
Dec 23 Javascript
详解Vue-cli代理解决跨域问题
Sep 27 Javascript
Vue动态控制input的disabled属性的方法
Jun 26 Javascript
JavaScript forEach中return失效问题解决方案
Jun 01 Javascript
详解vue身份认证管理和租户管理
May 25 Vue.js
javascript条件式访问属性和箭头函数介绍
Nov 17 Javascript
vue实现省市区联动 element-china-area-data插件
Apr 22 Vue.js
深入浅出理解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面试题(对属性或方法的访问控制)
2012/09/13 PHP
PHP中计算字符串相似度的函数代码
2012/12/29 PHP
php 批量添加多行文本框textarea一行一个
2014/06/03 PHP
Thinkphp搜索时首页分页和搜索页保持条件分页的方法
2014/12/05 PHP
深入浅析php中sprintf与printf函数的用法及区别
2016/01/08 PHP
关于PHP 如何用 curl 读取 HTTP chunked 数据
2016/02/26 PHP
PHP对称加密函数实现数据的加密解密
2016/10/27 PHP
常用PHP封装分页工具类
2017/01/14 PHP
php中用unset销毁变量并释放内存
2020/05/10 PHP
firefox火狐浏览器与与ie兼容的2个问题总结
2010/07/20 Javascript
jquery蒙版控件实现代码
2010/12/08 Javascript
基于jQuery的计算文本框字数的代码
2012/06/06 Javascript
JS对话框_JS模态对话框showModalDialog用法总结
2014/01/11 Javascript
js对象的复制继承实例
2015/01/10 Javascript
jquery选择器中的空格与大于号&gt;、加号+与波浪号~的区别介绍
2016/06/24 Javascript
js格式化时间的简单实例
2016/11/27 Javascript
jquery实现数字输入框
2017/02/22 Javascript
Javascript操作dom对象之select全面解析
2017/04/24 Javascript
详解nodeJs文件系统(fs)与流(stream)
2018/01/24 NodeJs
Node.js API详解之 net模块实例分析
2020/05/18 Javascript
jQuery实现日历效果
2020/09/11 jQuery
[00:23]DOTA2群星共贺开放测试 25日无码时代来袭
2013/09/23 DOTA
[02:20]DOTA2中文配音宣传片
2013/05/22 DOTA
用tensorflow搭建CNN的方法
2018/03/05 Python
Python使用matplotlib实现的图像读取、切割裁剪功能示例
2018/04/28 Python
Python中的引用知识点总结
2019/05/20 Python
Jupyter Notebook远程登录及密码设置操作
2020/04/10 Python
python中not、and和or的优先级与详细用法介绍
2020/11/03 Python
CSS实现圆形放大镜狙击镜效果 只有圆圈里的放大
2012/12/10 HTML / CSS
化学相关工作求职信
2013/10/02 职场文书
总监职责范文
2013/11/09 职场文书
开业庆典邀请函
2014/01/08 职场文书
幼儿园教师节活动方案
2014/02/02 职场文书
元旦趣味活动方案
2014/08/22 职场文书
2015年工程师工作总结
2015/04/30 职场文书
2015年教研室工作总结范文
2015/05/23 职场文书