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

Vue.js 2多级下拉菜单失效无报错,如何实现嵌套下拉菜单?

Vue.js 2 多级下拉菜单实现方案

原代码核心问题

  • 所有嵌套子菜单共用同一个submenuOpen状态变量,点击任意子菜单会触发全局状态切换,导致多级菜单无法独立控制展开/收起。
  • 缺少点击页面外部区域关闭菜单的逻辑,菜单展开后只能通过原按钮关闭,交互体验差。
  • 依赖的Bootstrap类缺少对应样式支撑,导致菜单布局异常(比如默认显示而非隐藏)。

修正实现方案

关键改进点

  1. 为每个子菜单维护独立状态:用对象存储不同层级子菜单的状态,通过唯一标识区分控制。
  2. 添加外部点击关闭逻辑:利用事件冒泡机制,点击页面其他区域时关闭所有下拉菜单。
  3. 补充基础样式:内置下拉菜单必要样式,避免依赖外部CSS库导致的显示问题。

完整修正代码

<template>
  <div class="container" @click="closeAllDropdowns">
    <div class="dropdown" @click.stop>
      <button class="btn btn-default" @click="toggleDropdown">
        Tutorials <span class="caret"></span>
      </button>
      <ul class="dropdown-menu" v-show="dropdownOpen">
        <li><a href="#">HTML</a></li>
        <li><a href="#">CSS</a></li>
        <li class="dropdown-submenu" @click.stop>
          <a href="#" @click="toggleSubmenu('level2')">
            New dropdown <span class="caret"></span>
          </a>
          <ul class="dropdown-menu" v-show="submenuStates.level2">
            <li><a href="#">2nd level dropdown</a></li>
            <li><a href="#">2nd level dropdown</a></li>
            <li class="dropdown-submenu" @click.stop>
              <a href="#" @click="toggleSubmenu('level3')">
                Another dropdown <span class="caret"></span>
              </a>
              <ul class="dropdown-menu" v-show="submenuStates.level3">
                <li><a href="#">3rd level dropdown</a></li>
                <li><a href="#">3rd level dropdown</a></li>
              </ul>
            </li>
          </ul>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dropdownOpen: false,
      // 用对象存储每个子菜单的独立状态
      submenuStates: {
        level2: false,
        level3: false
      }
    };
  },
  methods: {
    toggleDropdown() {
      this.dropdownOpen = !this.dropdownOpen;
      // 展开主菜单时重置所有子菜单状态(可选)
      if (this.dropdownOpen) {
        this.submenuStates = { level2: false, level3: false };
      }
    },
    toggleSubmenu(key) {
      this.submenuStates[key] = !this.submenuStates[key];
      // 展开当前子菜单时关闭其他同级子菜单(可选)
      Object.keys(this.submenuStates).forEach(k => {
        if (k !== key) this.submenuStates[k] = false;
      });
    },
    closeAllDropdowns() {
      this.dropdownOpen = false;
      this.submenuStates = { level2: false, level3: false };
    }
  }
};
</script>

<style>
/* 基础下拉菜单样式,无需依赖外部库 */
.dropdown {
  position: relative;
  display: inline-block;
}
.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 1000;
  min-width: 160px;
  padding: 5px 0;
  margin: 2px 0 0;
  font-size: 14px;
  list-style: none;
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-shadow: 0 6px 12px rgba(0,0,0,.175);
  display: none;
}
/* 配合v-show控制显示 */
.dropdown-menu[v-show="true"] {
  display: block;
}
.dropdown-submenu {
  position: relative;
}
.dropdown-submenu .dropdown-menu {
  top: 0;
  left: 100%;
  margin-top: -1px;
}
.btn {
  display: inline-block;
  padding: 6px 12px;
  font-size: 14px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background-color: #fff;
  cursor: pointer;
}
.caret {
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 2px;
  vertical-align: middle;
  border-top: 4px solid;
  border-right: 4px solid transparent;
  border-left: 4px solid transparent;
}
</style>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 04:59:54