视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
vue中的事件阻止冒泡的用法详解
2020-11-27 19:32:51 责编:小采
文档
 这篇文章给大家介绍的内容是关于vue中的事件阻止冒泡的用法详解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

冒泡的表现

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

他们的DOM结构如下:

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

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

图中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 提供了事件修饰符,修饰符是由点开头的指令后缀来表示的。这些事件修饰符主要有以下几个:

  • stop

  • prevent

  • capture

  • prevent

  • self

  • once

  • passive

  • 看到没有,第一个'stop'就是我们想要的!
    这些修饰符正是为了解决这些问题而生的。也就说我们只需要在模板中这样写就搞定停止冒泡了。

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

    很完美有没有,这就不用在事件响应逻辑中去处理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>
    
    <!-- 添加事件时使用事件捕获模式 -->
    <!-- 即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理 -->
    <p v-on:click.capture="doThis">...</p>
    
    <!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
    <!-- 即事件不是从内部元素触发的 -->
    <p v-on:click.self="doThat">...</p>

    相关文章推荐:

    vue.js图片如何转Base上传图片并预览

    vue中如何来定义全局变量和全局方法?(代码)

    下载本文
    显示全文
    专题