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

如何在Angular+TypeScript+Ionic中为现有菜单添加二级子菜单

在Angular+Ionic项目中给Settings菜单添加可展开二级子菜单

1. 调整菜单数据结构(app.component.ts)

先修改appPages的结构,给Settings项添加子菜单列表,同时新增控制展开状态的变量和方法:

// 组件类内新增变量
expandedMenuId: string | null = null;
selectedIndex: number = 0;

initializeApp () {
    this.appPages = [
      {
        title: 'Home',
        url: '/home',
        image: 'assets/images/menu/home.svg',
        color: 'success'
      },
      {
        title: 'Profile',
        url: '/profile',
        image: 'assets/images/menu/profile.svg',
        color: 'tertiary'
      },
      {
        title: 'Settings',
        image: 'assets/images/menu/enter.svg',
        color: 'gray-light',
        // 添加二级子菜单
        children: [
          { title: 'Account Settings', url: '/settings/account', color: 'gray-light' },
          { title: 'Notification Settings', url: '/settings/notifications', color: 'gray-light' },
          { title: 'Privacy Settings', url: '/settings/privacy', color: 'gray-light' }
        ]
      }
    ];
  }

// 切换菜单展开/收起状态的方法
toggleMenuExpand(page: any) {
  if (page.children) {
    this.expandedMenuId = this.expandedMenuId === page.title ? null : page.title;
  }
}

2. 修改菜单模板(app.component.html)

更新模板逻辑,支持渲染二级子菜单,点击父项切换展开状态,子项单独处理页面跳转:

<ion-app>
  <ion-split-pane contentId="maincontent" [when]="showSplitPane && false">
    <ion-menu swipe-gesture="false" contentId="maincontent" id="mainmenu" menuId="mainmenu" type="overlay">
      <ion-content>
        <ion-list>
          <!-- 遍历一级菜单 -->
          <ng-container *ngFor="let p of appPages; let i = index">
            <!-- 无二级菜单的普通项 -->
            <ion-menu-toggle auto-hide="false" *ngIf="!p.children">
              <ion-item 
                (click)="selectedIndex = i" 
                routerDirection="root" 
                [routerLink]="p.url" 
                lines="none"
                detail="false" 
                [color]="p.color"
                [class.bold]="selectedIndex == i">
                <ion-icon slot="start" [src]="p.image"></ion-icon>
                <ion-label class="lighter">{{ p.title }}</ion-label>
                <ion-icon class="ion-no-margin" icon="chevron-forward-sharp" color="black"></ion-icon>
              </ion-item>
            </ion-menu-toggle>

            <!-- 带二级菜单的父项 -->
            <ng-container *ngIf="p.children">
              <ion-item 
                (click)="toggleMenuExpand(p); selectedIndex = i" 
                lines="none"
                detail="false" 
                [color]="p.color"
                [class.bold]="selectedIndex == i">
                <ion-icon slot="start" [src]="p.image"></ion-icon>
                <ion-label class="lighter">{{ p.title }}</ion-label>
                <!-- 根据展开状态切换箭头方向 -->
                <ion-icon class="ion-no-margin" 
                          [icon]="expandedMenuId === p.title ? 'chevron-down-sharp' : 'chevron-forward-sharp'" 
                          color="black"></ion-icon>
              </ion-item>

              <!-- 渲染二级子菜单 -->
              <ion-list *ngIf="expandedMenuId === p.title" class="submenu">
                <ion-menu-toggle auto-hide="false" *ngFor="let child of p.children">
                  <ion-item 
                    routerDirection="root" 
                    [routerLink]="child.url" 
                    lines="none"
                    detail="false" 
                    [color]="child.color">
                    <ion-label class="lighter" style="padding-left: 20px;">{{ child.title }}</ion-label>
                    <ion-icon class="ion-no-margin" icon="chevron-forward-sharp" color="black"></ion-icon>
                  </ion-item>
                </ion-menu-toggle>
              </ion-list>
            </ng-container>
          </ng-container>
        </ion-list>
      </ion-content>
    </ion-menu>
    <ion-router-outlet id="maincontent" maincontent></ion-router-outlet>
  </ion-split-pane>
</ion-app>

3. 配置子菜单路由

推荐在Settings模块的路由文件中配置子路由(更符合模块化规范):

// settings-routing.module.ts
const routes: Routes = [
  {
    path: '',
    component: SettingsPage,
    children: [
      { path: 'account', loadChildren: () => import('./account/account.module').then(m => m.AccountModule) },
      { path: 'notifications', loadChildren: () => import('./notifications/notifications.module').then(m => m.NotificationsModule) },
      { path: 'privacy', loadChildren: () => import('./privacy/privacy.module').then(m => m.PrivacyModule) },
      { path: '', redirectTo: 'account', pathMatch: 'full' } // 默认跳转到第一个子页面
    ]
  }
];

如果需要在全局路由中配置,可修改app-routing.module.ts:

const routes: Routes = [
  { path: '', redirectTo: 'login', pathMatch: 'full' },
  { path: 'home', loadChildren: () => import('./modules/home/home.module').then(m => m.HomeModule) },
  { path: 'profile', loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule) },
  { 
    path: 'settings', 
    loadChildren: () => import('./modules/settings/settings.module').then(m => m.SettingsModule),
    children: [
      { path: 'account', loadChildren: () => import('./modules/settings/account/account.module').then(m => m.AccountModule) },
      { path: 'notifications', loadChildren: () => import('./modules/settings/notifications/notifications.module').then(m => m.NotificationsModule) },
      { path: 'privacy', loadChildren: () => import('./modules/settings/privacy/privacy.module').then(m => m.PrivacyModule) },
      { path: '', redirectTo: 'account', pathMatch: 'full' }
    ]
  },
  { path: '**', redirectTo: 'login', pathMatch: 'full' }
];

4. 样式优化(可选)

给子菜单添加缩进和区分样式,在组件样式或全局样式中添加:

.submenu ion-item {
  --padding-start: 40px;
  --background: #f5f5f5;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 22:33:33