实际开发中遇到的事件冒泡——为什么我的弹框关不掉了

写在前面

  • 冒泡这个问题非常基础,本以为对此已经足够了解,没想到一个不慎还是在实际开发中踩了冒泡的坑。
  • 所以掌握好基础非常重要。

注:该笔记中示例是一个vue+vant+nuxt项目。

知识点

事件冒泡:基于dom树形结构,事件会顺着触发元素向上冒泡。当子元素触发事件,事件会依次往上级传递,每一级都可以感知到事件,直到传递到根元素。

简单的示例:

<div id="app">
  <div class="father" @click="myConsole('father')">
    <div class="son" @click="myConsole('son')">
      son
    </div>
  </div>
</div>

点击son的时候,会先后打印出:son, father。

实战中遇到的问题

点击关闭弹框的按钮,弹框反复闪烁(关闭-打卡-关闭-打开……),关闭不了。

页面示例:

问题代码:

<template>
	<!--  打开微信扫码的按钮  -->
  <div class="wechat-button" @click="showQRCodeDialog">
    <img class="wechat-button-logo" src="./img/logo.png" alt="logo">
    <span class="wechat-button-text">打开微信扫码</span>
    <img class="wechat-button-more" src="./img/icon_more.png" alt="more">
		<!-- 弹框 -->
    <WechatQRCodeDialog :visible.sync="QRCodeDialogShow" />
  </div>
</template>

分析原因

第一步,点击按钮触发showQRCodeDialog事件,出现弹框。

第二步,点击弹框上的关闭按钮,本应该是关闭弹框的,但是因为弹框放在了按钮里面,showQRCodeDialog事件相当于也绑在弹框上。

归根结底是因为事件冒泡——点击弹框的时候,点击事件穿透到了button上面。触发了showQRCodeDialog

扫描二维码关注公众号,回复: 15180186 查看本文章

注意,默认情况下,vant 的弹框就是插入到我们写的位置的,不像element的弹框是插入到body的

当时一下子还没想到冒泡上去。因为当时一直在做后台管理系统,用的element,很久没用vant的dialog了,下意识以为dialog是在button外面的。

所以有些坑真的是很基础的东西造成的。这说明基础的东西真的不容忽视。

解决方法

方案1:Dialog外面加一个@click.stop 阻止冒泡。

<template>
  <div class="wechat-QRCode-dialog-box" @click.stop>
    <van-dialog
      v-model="show"
      class="wechat-QRCode-dialog"
      title="微信搜一搜"
      cancel-button-text="关闭"
      cancel-button-color="#333"
      :show-confirm-button="false"
      :show-cancel-button="true"
      :close-on-click-overlay="true"
    >
      <img class="wechat-QRCode-img" src="./img/wechat-search.png" alt="微信搜一搜">
      <div class="official-account-name">
        <span>互联网医院</span>
        <span class="official-account-name-button" @click="copyName">复制</span>
      </div>
    </van-dialog>
  </div>
</template>

方案2:改变一下button组件的结构:

<template>
  <div class="wechat-button-box">
    <div class="wechat-button" @click="showQRCodeDialog">
      <img class="wechat-button-logo" src="./img/logo.png" alt="logo">
      <span class="wechat-button-text">打开微信扫码</span>
      <img class="wechat-button-more" src="./img/icon_more.png" alt="more">
    </div>
    <WechatQRCodeDialog :visible.sync="QRCodeDialogShow" />
  </div>
</template>

不要偷懒,再在外面套一个div就好啦,不要把弹框放在按钮里面。那天正好偷了个懒,于是就踩了个小坑。

知识点补充

事件冒泡的应用场景:

  • 事件代理。

猜你喜欢

转载自blog.csdn.net/dongkeai/article/details/127392623