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

使用Bootstrap 5的menu-link/menu-toggle类时Angular子菜单不显示

问题:Bootstrap模板迁移Angular后主菜单点击无法显示子菜单

我正在把Bootstrap HTML模板迁移到Angular,页面设计已经完成,但点击主菜单时,对应的子菜单无法正常展开显示。以下是相关代码:

index.html 代码

<html
  lang="en"
  class="light-style layout-navbar-fixed layout-menu-fixed layout-menu-collapsed"
  dir="ltr"
  data-theme="theme-default"
  data-assets-path="/assets/"
  data-template="vertical-menu-template"
>
<head>
  <meta charset="utf-8">
  <title>Templates</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">   
  <!--<link href='https://unpkg.com/boxicons@2.1.2/css/boxicons.min.css' rel='stylesheet'>-->
  <script src="/assets/vendor/js/helpers.js"></script>    
  <!--<script src="/assets/vendor/js/template-customizer.js"></script>-->
  <script src="/assets/js/config.js"></script>
  <link href="https://cdn.jsdelivr.net/css-toggle-switch/latest/toggle-switch.css" rel="stylesheet" />
    
  <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js" integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" crossorigin="anonymous"></script>
</head>
<body>
  <app-root></app-root>  
    <script src="/assets/vendor/libs/jquery/jquery.js"></script>   
    <script src="/assets/vendor/libs/popper/popper.js"></script>  
    <script src="/assets/vendor/js/bootstrap.js"></script> 
    <script src="/assets/vendor/libs/perfect-scrollbar/perfect-scrollbar.js"></script>
    <script src="/assets/vendor/libs/hammer/hammer.js"></script>
    <script src="/assets/vendor/libs/select2/select2.js"></script>
    <!--<script src="/assets/vendor/libs/tagify/tagify.js"></script>-->
    <script src="/assets/vendor/libs/bootstrap-select/bootstrap-select.js"></script>    
    <script src="/assets/vendor/js/menu.js"></script>     
    
    
    <!-- endbuild -->

    <!-- Vendors JS -->
    <script src="/assets/vendor/libs/apex-charts/apexcharts.js"></script>
</body>
</html>

Header组件菜单代码

<ul class="menu-inner py-1">
          <!-- Dashboard -->
          <li class="menu-item">            
            <a href="#" class="menu-link menu-toggle">
              <i class="menu-icon tf-icons bx bxs-book-reader" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Course Master"></i>
              <div data-i18n="Course Master">Course</div>
            </a>
            <ul class="menu-sub">
              <li class="menu-item">
                    <a href="manage-course.html" class="menu-link">
                      <div data-i18n="Manage Course">Manage Course</div>
                    </a>
              </li>
              <li class="menu-item">
                <a href="approve-course-master-list.html" class="menu-link">
                  <div data-i18n="Approve Course">Approve Course</div>
                </a>
              </li>
          </ul>
          </li>
</ul>

解决方案

1. 修复脚本重复加载与顺序问题

你当前在index.html中重复加载了jQuery、Popper和Bootstrap(CDN版+本地版),这会导致库冲突,直接删除其中一套即可。建议保留本地assets版本(模板配套的menu.js通常依赖本地库),并确保脚本按jQuery → Popper → Bootstrap → menu.js的顺序加载,移除head里的CDN版jQuery、Popper、Bootstrap脚本。

2. 确保菜单脚本在Angular组件渲染后初始化

Angular组件是动态渲染DOM的,index.html末尾加载的menu.js可能在Header组件DOM未渲染完成时就执行,导致点击事件绑定失效。可以在Header组件的ngAfterViewInit钩子中手动初始化菜单逻辑:

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

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements AfterViewInit {

  ngAfterViewInit(): void {
    // 绑定菜单切换事件
    document.querySelectorAll('.menu-toggle').forEach(toggle => {
      toggle.addEventListener('click', (e) => {
        e.preventDefault();
        const parentItem = toggle.closest('.menu-item');
        parentItem?.classList.toggle('open');
      });
    });
  }
}

3. 替换Angular路由链接格式

传统href会触发页面刷新,导致菜单状态丢失,需要用Angular的routerLink替代,同时在路由模块中配置对应路径:
修改Header组件代码:

<ul class="menu-inner py-1">
  <li class="menu-item">            
    <a href="#" class="menu-link menu-toggle">
      <i class="menu-icon tf-icons bx bxs-book-reader" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Course Master"></i>
      <div data-i18n="Course Master">Course</div>
    </a>
    <ul class="menu-sub">
      <li class="menu-item">
            <a routerLink="/manage-course" class="menu-link">
              <div data-i18n="Manage Course">Manage Course</div>
            </a>
      </li>
      <li class="menu-item">
        <a routerLink="/approve-course" class="menu-link">
          <div data-i18n="Approve Course">Approve Course</div>
        </a>
      </li>
    </ul>
  </li>
</ul>

4. 验证CSS类状态切换规则

确认模板CSS中,父级menu-item添加open类时,子菜单menu-sub的显示规则正确(例如display: block),如果默认规则缺失,可手动补充:

.menu-item.open .menu-sub {
  display: block !important;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 02:01:17