如何在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
相关产品推荐
相关产品推荐

