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

创建垂直多级菜单:子菜单显示异常,求排查及jQuery/Angular实现方案

问题分析与解决方案

首先,你遇到的问题核心在于Bootstrap的nav-tabs组件默认并不支持嵌套子菜单的交互与样式——它本身是为标签页切换设计的,没有内置下拉/子菜单的逻辑。接下来我一步步帮你排查和解决:

一、现有代码的问题排查与修复

1. 缺少子菜单的基础样式

默认情况下,嵌套的<ul>子菜单不会被正确渲染,需要先添加CSS来控制它的显示/隐藏:

/* 垂直导航栏基础样式调整 */
.nav.nav-tabs {
  flex-direction: column; /* 改为垂直排列 */
  border-bottom: none;
}
.nav.nav-tabs li {
  position: relative; /* 为子菜单定位做准备 */
  padding: 8px 0;
}
/* 子菜单默认隐藏 */
.nav.nav-tabs li ul {
  display: none;
  position: absolute;
  left: 100%; /* 子菜单在父菜单右侧显示 */
  top: 0;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 0 4px 4px 0;
  list-style: none;
  padding: 0;
  min-width: 150px;
}
.nav.nav-tabs li ul li {
  padding: 8px 12px;
}
/* 鼠标悬停时显示子菜单 */
.nav.nav-tabs li:hover ul {
  display: block;
}

2. 点击触发的交互逻辑(可选)

如果需要点击主菜单来切换子菜单显示,添加一段简单的jQuery脚本:

$(document).ready(function() {
  $('.nav.nav-tabs li:has(ul)').click(function(e) {
    e.preventDefault(); // 阻止默认跳转行为
    $(this).find('ul').toggle();
    // 关闭其他已打开的子菜单
    $(this).siblings().find('ul').hide();
  });
});

把上面的CSS和JS添加到你的代码中,子菜单就能正常显示了。

二、更规范的实现方式

1. jQuery + Bootstrap 原生下拉组件改造

Bootstrap本身有成熟的dropdown组件,基于它实现垂直导航+子菜单更符合框架规范,无需自己写大量自定义代码:

<div class="col-xs-2 col-sm-2">
  <ul class="nav flex-column">
    <li class="nav-item dropdown">
      <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown">
        aaa
      </a>
      <ul class="dropdown-menu">
        <li><a class="dropdown-item" href="#">xxxxxxx</a></li>
        <li><a class="dropdown-item" href="#">yyyyyyyy</a></li>
        <li><a class="dropdown-item" href="#">cccccc</a></li>
      </ul>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#">bbb</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#">ccc</a>
    </li>
  </ul>
</div>

2. Angular 实现方式

如果用Angular,推荐两种主流方案:

方案一:Angular Material 菜单组件

Angular Material提供了开箱即用的嵌套菜单组件,稳定性和兼容性拉满:

<mat-nav-list>
  <mat-list-item>
    <button mat-button [matMenuTriggerFor]="subMenu">aaa</button>
    <mat-menu #subMenu="matMenu">
      <button mat-menu-item>xxxxxxx</button>
      <button mat-menu-item>yyyyyyyy</button>
      <button mat-menu-item>cccccc</button>
    </mat-menu>
  </mat-list-item>
  <a mat-list-item href="#">bbb</a>
  <a mat-list-item href="#">ccc</a>
</mat-nav-list>

使用前需要先在Angular模块中导入MatMenuModule和MatListModule。

方案二:自定义Angular组件

如果不想依赖第三方库,可以自己实现简易的子菜单逻辑:

<ul class="vertical-nav">
  <li (click)="toggleSubMenu($event)" class="nav-item">
    <a href="#">aaa</a>
    <ul [class.show]="isSubMenuOpen">
      <li><a href="#">xxxxxxx</a></li>
      <li><a href="#">yyyyyyyy</a></li>
      <li><a href="#">cccccc</a></li>
    </ul>
  </li>
  <li class="nav-item"><a href="#">bbb</a></li>
  <li class="nav-item"><a href="#">ccc</a></li>
</ul>

对应的组件TS代码:

import { Component } from '@angular/core';

@Component({
  selector: 'app-vertical-nav',
  templateUrl: './vertical-nav.component.html',
  styleUrls: ['./vertical-nav.component.css']
})
export class VerticalNavComponent {
  isSubMenuOpen = false;

  toggleSubMenu(event: Event) {
    event.stopPropagation();
    this.isSubMenuOpen = !this.isSubMenuOpen;
  }
}

配套CSS:

.vertical-nav {
  list-style: none;
  padding: 0;
}
.nav-item {
  position: relative;
  padding: 8px 0;
}
.nav-item ul {
  display: none;
  position: absolute;
  left: 100%;
  top: 0;
  background: #fff;
  border: 1px solid #ddd;
  padding: 8px 0;
  min-width: 150px;
}
.nav-item ul.show {
  display: block;
}
.nav-item ul li {
  padding: 4px 16px;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:07:55