You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue悬停Popup Menu异常关闭求助:移入菜单时菜单消失

解决Vue悬停下拉菜单消失的问题

问题根源

  1. 下拉菜单与触发按钮之间存在空白间隙,鼠标从按钮移向菜单时,会先离开包含按钮和菜单的.drop-down容器,触发mouseleave事件直接关闭菜单
  2. 菜单采用绝对定位但未绑定相对定位的父容器,导致位置计算脱离触发按钮范围,进一步放大了间隙问题

修复步骤

  • 给.drop-down容器添加position: relative,让菜单的绝对定位基于该容器
  • 修改.thisDropDown的top值为calc(100% + 8px),使菜单紧贴按钮下方(8px为可调整的间距),移除原有的left: 0; right: 0(如需保持菜单宽度与父容器一致,可改为width: 100%)
  • 在关闭方法中添加延迟,并在打开方法中清除延迟定时器,避免快速操作时误关闭

修改后的完整代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
  <style>
    * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

.header {
    width: 100%;
    height: 70px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    background-color: #cccccc;
}

.container {
    max-width: 1280px;
    margin: 0 auto;
}

.button-drop {
    background-color: #0ff;
    padding: 20px 30px;
    border-radius: 5px;
    cursor: pointer;
}

/* 给父容器添加相对定位 */
.drop-down {
    position: relative;
}

.thisDropDown {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translate(0, -8px);
    transition: .3s all;
    position: absolute;
    /* 调整top值,紧贴按钮下方 */
    top: calc(100% + 8px);
    background: #fff;
    box-shadow: 0 4px 4px rgba(0, 0, 0, .05), 0 -1px 2px rgba(0, 0, 0, .04), 0 0 4px rgba(0, 0, 0, .05), 0 4px 8px rgba(0, 0, 0, .05);
    border-radius: 5px;
    padding: 40px;
    /* 保持菜单宽度与父容器一致 */
    width: 100%;
    z-index: 2;
}

.thisDropDown.active {
    visibility: visible;
    opacity: 1;
    pointer-events: auto;
    transform: translate(0, 0);
}

.thisDropDownSelect {
    display: flex;
    flex-direction: column;
    padding: 20px;
}

a {
    color: aliceblue;
}
  </style>
</head>
<body>
  <div id="app">
    <header class="header container">
        <div><a href="">LOGO</a></div>
        <div class="drop-down" @mouseenter="openDropdown" @mouseleave="closeDropdown">
            <span class="button-drop">Open Menu</span>
            <div class="thisDropDown" :class="{ active: isDropdownOpen }">
                <div class="thisDropDownSection">
                    <div class="thisDropDownSelect">
                        <span class="thisDropDownTit">Menu 1</span>
                        <span class="thisDropDownTit">Menu 2</span>
                        <span class="thisDropDownTit">Menu 3</span>
                    </div>
                </div>
            </div>
        </div>
    </header>
  </div>
  <script>
    new Vue({
      el: '#app',
      data: {
        isDropdownOpen: false,
        closeTimer: null
      },
      methods: {
        openDropdown() {
          // 清除关闭定时器
          clearTimeout(this.closeTimer);
          this.isDropdownOpen = true;
        },
        closeDropdown() {
          // 添加300ms延迟,避免误触发
          this.closeTimer = setTimeout(() => {
            this.isDropdownOpen = false;
          }, 300);
        }
      },
      // 组件销毁时清除定时器
      beforeDestroy() {
        clearTimeout(this.closeTimer);
      }
    });
  </script>
</body>
</html>

内容的提问来源于stack exchange,提问作者JuliaBland299

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 19:45:28