记录开源项目中点击空白区域关闭一二级菜单的问题

2 篇文章 0 订阅
2 篇文章 0 订阅

今天在开发TinyEngine华为低代码引擎开源项目时,我遇到了一个细节的问题:原本是点击标题显示菜单,再次点击标题或点击空白区域关闭菜单。中国没错的,然后呢,这里我手动实现了一个二级菜单,二级菜单内部点击是会切换该选项后面跟着的图标的,我希望点击完之后只是图标变化,但点击菜单内部时菜单也会关闭,虽然也能用,但很影响用户体验,这不是我期望的行为。
在这里插入图片描述

简单的描述一下问题就是:
在项目中,我实现了一个点击标题显示菜单的功能,并在点击空白区域时关闭菜单。然而,点击菜单内部时菜单也会关闭,这导致用户体验不佳。

这里先贴一下问题代码段

模板部分
<template>
  <div class="top-panel-logo">
    <h1 class="logo-wrap" @click.stop="handleTitleClick">
      <div class="menu-icon-wrapper">
        <svg-icon name="menu"></svg-icon>
        <span class="menu-title">{{ state.appName }}</span>
      </div>
    </h1>
    <div v-if="state.showMenu" class="main-menu">
      <ul>
        <li @click="handleClick({ code: 'publishApp' })">
          <span class="menu-item">发布应用</span>
        </li>
        <li @mouseenter="state.showSubMenu = true" @mouseleave="state.showSubMenu = false" >
          <span class="menu-item">显示设置</span>
          <icon-right></icon-right>
        </li>
      </ul>
    </div>
  </div>
   <div
      v-if="state.showMenu && state.showSubMenu"
      class="sub-menu"
      @mouseenter="state.showSubMenu = true"
      @mouseleave="state.showSubMenu = false"
    >
      <ul>
        <li v-for="(item, index) in subMenus" :key="index" @click="changeShowState(item)">
          <span class="menu-item">{{ item.name }}</span>
          <span v-show="item.isShow"></span><!--二级选项状态标识-->
        </li>
      </ul>
    </div>
    <!--省略其他内容-->
  </div>
</template>
脚本部分
<script setup>
import ...省略

const state = reactive({
  showMenu: false,
  showSubMenu: false,
});
const subMenus = ref([
  { name: '左侧活动栏', code: 'changeLeft', isShow: true },
  { name: '右侧活动栏', code: 'changeRight', isShow: true },
  { name: '底部活动栏', code: 'changeBottom', isShow: true }
])

const handleCloseMenu = () => {
  state.showMenu = false
  state.showSubMenu = false
  window.removeEventListener('click', handleCloseMenu)
}

const handleTitleClick = () => {
  state.showMenu = !state.showMenu
  if (state.showMenu) {
    window.addEventListener('click', handleCloseMenu)
  } else {
    window.removeEventListener('click', handleCloseMenu)
  }
}

onUnmounted(() => {
  window.removeEventListener('click', handleCloseMenu)
})
</script>

在点击标题时会切换 state.showMenu 的值并在 window 上添加或移除 click 事件监听器,这里是为了在点击空白区域时关闭菜单。
但是!!!!这样会导致点击菜单内部时也会关闭菜单!(在增加显示设置菜单时其实这个是没有影响的,因为增加该需求前,这里原本只有一个发布页面按钮,点击时会弹出悬浮操作框,此时关闭操作栏的逻辑也是没有问题的,但这实际上是触发了window上的事件实现的)

所以问题的根本原因在于 window 上的 click 事件监听器会在点击菜单内部时触发,从而调用 handleCloseMenu 方法关闭菜单
❗💥我们需要一种方法来阻止事件冒泡,使得点击菜单内部时不会触发 window 上的 click 事件。

解决方法

可以使用 Vue.js 的事件修饰符 @click.stop 来阻止事件冒泡,从而防止点击菜单内部时关闭菜单

解决方案步骤

  1. 在菜单的 @click 事件上添加 .stop 修饰符

    <div v-if="state.showMenu" class="main-menu" @click.stop>
      <ul>
        <li @click="handleClick({ code: 'publishApp' })">
          <span class="menu-item">发布应用</span>
        </li>
        <!-- 其他菜单项 -->
      </ul>
    </div>
    

    这样点击菜单内部时事件不会冒泡到 window,就不会触发 handleCloseMenu 方法

  2. 在子菜单的 @click 事件上添加 .stop 修饰符

    如果有子菜单同样需要在子菜单的 @click 事件上添加 .stop 修饰符:

    <div
      v-if="state.showMenu && state.showSubMenu"
      class="sub-menu"
      @mouseenter="state.showSubMenu = true"
      @mouseleave="state.showSubMenu = false"
      @click.stop
    >
      <ul>
        <li v-for="(item, index) in subMenus" :key="index" @click="changeShowState(item)">
          <span class="menu-item">{{ item.name }}</span>
          <span v-show="item.isShow"></span>
        </li>
      </ul>
    </div>
    

    这样点击子菜单内部时,事件同样不会冒泡到 window,就不会触发 handleCloseMenu 方法
    完。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二级分销开源项目Java是一个基于Java编程语言开发的开源项目。 二级分销是一种商业模式,它通过建立多层级的分销网络,让更多的人参与到销售过程,从而达到商品或服务的更广泛传播和销售的目的。而Java是一种跨平台的编程语言,具有良好的可移植性和易于学习的特点,因此在开发二级分销项目时,选择Java语言可以提高开发效率和项目的可扩展性。 通过开源项目的方式开发二级分销系统,可以让更多的开发者参与到项目来,共同完善和改进项目。开源项目将源代码公开,使得任何人都可以自由地使用和修改代码。开源项目的好处是可以节约开发成本,提高系统的透明度和安全性,同时也可以获得开发者的建议和反馈。 在Java开源社区,已经有一些优秀的二级分销开源项目,例如淘宝分销系统、微信分销系统等。这些项目提供了基础的功能模块,如商品管理、订单管理、分销商管理、佣金计算等,同时也提供了丰富的API接口,方便与其他系统进行集成。 开发一个二级分销开源项目需要考虑到系统的稳定性、安全性和可扩展性。可以利用Java的各种开发框架和工具,如Spring、Hibernate、MyBatis等来加快开发进度,同时也可以利用一些开源组件或者第三方库来提供更丰富的功能。 总而言之,二级分销开源项目Java是一个利用Java编程语言开发的开源项目,它可以让更多的开发者参与到项目来,共同完善和改进项目。在开发过程,需考虑系统的稳定性、安全性和可扩展性,利用Java的各种框架和工具可以提高开发效率和项目的可扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值