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

如何用Angular 5结合Angular Material实现带子菜单的导航菜单

解决Angular 5 Material子菜单展开问题

嘿,我明白你现在的困扰——用mat-nav-list和mat-list-item展示菜单时,父项点击展开子菜单的功能没实现对吧?别担心,咱们一步步来搞定它:

第一步:组件类添加状态管理

首先你需要在组件里跟踪当前展开的父菜单,这样才能控制子菜单的显示/隐藏。另外还要写一个切换展开状态的方法:

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

// 基于你提供的接口扩展完整菜单结构
export interface MenuItem {
  state: string;
  name: string;
  type: 'link' | 'sub';
  children?: ChildrenItems[];
}

export interface ChildrenItems {
  state: string;
  name: string;
  type?: string;
}

@Component({
  selector: 'app-side-menu',
  templateUrl: './side-menu.component.html',
  styleUrls: ['./side-menu.component.css']
})
export class SideMenuComponent {
  // 模拟你的菜单数据源
  menuItems: MenuItem[] = [
    {
      state: 'dashboard',
      name: 'Dashboard',
      type: 'link'
    },
    {
      state: 'settings',
      name: 'Settings',
      type: 'sub',
      children: [
        { state: 'profile', name: 'Profile' },
        { state: 'notifications', name: 'Notifications' }
      ]
    }
  ];

  // 存储当前展开的父菜单state标识
  expandedMenu: string | null = null;

  // 切换菜单展开/收起状态
  toggleMenu(menuState: string): void {
    this.expandedMenu = this.expandedMenu === menuState ? null : menuState;
  }
}

第二步:修改模板结构实现嵌套菜单

在模板里,给父项添加点击事件,用*ngIf控制子菜单的显示,同时用图标给用户直观的展开状态提示:

<mat-nav-list>
  <!-- 遍历所有顶层菜单项 -->
  <ng-container *ngFor="let item of menuItems">
    <!-- 处理普通链接型菜单项 -->
    <a mat-list-item *ngIf="item.type === 'link'" [routerLink]="[item.state]">
      <span>{{ item.name }}</span>
    </a>

    <!-- 处理带子菜单的父项 -->
    <div *ngIf="item.type === 'sub'">
      <mat-list-item (click)="toggleMenu(item.state)" style="cursor: pointer;">
        <span>{{ item.name }}</span>
        <mat-icon style="margin-left: auto;">
          {{ expandedMenu === item.state ? 'expand_less' : 'expand_more' }}
        </mat-icon>
      </mat-list-item>

      <!-- 子菜单:仅当父菜单展开时显示 -->
      <mat-nav-list *ngIf="expandedMenu === item.state" class="sub-menu">
        <a mat-list-item *ngFor="let child of item.children" [routerLink]="[child.state]">
          <span>{{ child.name }}</span>
        </a>
      </mat-nav-list>
    </div>
  </ng-container>
</mat-nav-list>

第三步:添加样式优化子菜单层级

为了让子菜单的层级更清晰,给子菜单加个缩进样式:

.sub-menu {
  padding-left: 24px; /* 可根据需求调整缩进大小 */
}

关键逻辑说明

  • 用expandedMenu变量记录当前展开的父菜单标识(这里复用了state字段),点击父项时调用toggleMenu方法切换状态。
  • 子菜单通过*ngIf="expandedMenu === item.state"控制渲染,只有对应的父菜单被选中展开时才会显示。
  • 借助mat-icon的expand_more/expand_less图标,给用户直观的展开/收起视觉反馈。

这样调整之后,点击带有子菜单的父项就能正常展开/收起子菜单啦!

内容的提问来源于stack exchange,提问作者fariba.j

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:36:39