如何在Nebular菜单栏折叠时,以Popover形式展示子菜单?
Nebular菜单折叠时通过Popover展示子菜单(不触发主菜单项)
需求梳理
菜单展开状态:通过children[]正常展示子菜单;
菜单折叠状态:点击主菜单项不触发跳转/默认行为,弹出Popover展示子菜单。
实现步骤
1. 修正并优化菜单配置
先修正你提供的menuItems语法错误,同时新增标识字段区分需要Popover的菜单项,后续可根据菜单状态动态控制主菜单项的跳转行为:
import { NbMenuItem } from '@nebular/theme'; export const menuItems: NbMenuItem[] = [ { title: 'Dashboard', icon: { icon: 'dashboard', pack: 'icons' }, link: '/dashboard', home: false, }, { title: 'Card-Menu', icon: { icon: 'booking', pack: 'icons' }, link: '/cardMenu', home: true, }, { title: 'Manage Card', icon: { icon: 'Manage -icon', pack: 'icons' }, autoCollapse: true, button: 'cardButton', hasPopover: true, // 标记该菜单项在折叠时需要Popover children: [ { title: 'ABC', link: '/ABC' }, { title: 'xyz', link: '/xyz' }, ], }, ];
2. 自定义菜单模板,集成Popover
在菜单所在组件的模板中,使用NbMenu的自定义模板,结合侧边栏状态判断,为目标菜单项渲染Popover:
<nb-layout> <nb-sidebar #sidebar state="expanded" (stateChange)="onSidebarStateChange($event)"> <nb-menu [items]="menuItems"> <ng-template #itemTemplate let-item="item" let-expanded="expanded"> <!-- 展开状态或无需Popover的菜单项,用原生渲染逻辑 --> <ng-container *ngIf="!item.hasPopover || sidebar.isExpanded"> <nb-menu-item [item]="item" [expanded]="expanded"></nb-menu-item> </ng-container> <!-- 折叠状态下的Popover菜单 --> <ng-container *ngIf="item.hasPopover && !sidebar.isExpanded"> <button nbButton ghost (click)="$event.stopPropagation()" [nbPopover]="popoverContent" placement="right"> <nb-icon [icon]="item.icon.icon" [pack]="item.icon.pack"></nb-icon> </button> <ng-template #popoverContent> <nb-list> <nb-list-item *ngFor="let child of item.children" (click)="navigateTo(child.link)"> {{ child.title }} </nb-list-item> </nb-list> </ng-template> </ng-container> </ng-template> </nb-menu> </nb-sidebar> <nb-layout-column> <!-- 页面主内容区 --> </nb-layout-column> </nb-layout>
3. 组件逻辑实现
在组件类中处理侧边栏状态变化和页面跳转逻辑:
import { Component, ViewChild } from '@angular/core'; import { NbSidebarComponent, Router } from '@nebular/theme'; import { menuItems } from './path-to-your-menu-items'; // 替换为你的菜单文件路径 @Component({ selector: 'app-root', templateUrl: './app.component.html', }) export class AppComponent { @ViewChild('sidebar') sidebar!: NbSidebarComponent; menuItems = menuItems; constructor(private router: Router) {} onSidebarStateChange(state: string) { // 可选:根据侧边栏状态做额外逻辑处理 } navigateTo(link: string) { this.router.navigate([link]); } }
关键细节说明
- 用
$event.stopPropagation()阻止折叠状态下主按钮的默认点击行为,避免触发菜单的跳转/展开逻辑; - 通过
sidebar.isExpanded判断侧边栏状态,动态切换渲染模式; - Popover内容用
nb-list保持和原生菜单一致的样式,也可自定义样式匹配UI设计; - 若需要更复杂的Popover交互(如点击外部关闭),可结合
NbPopoverService手动控制显示/隐藏。
内容的提问来源于stack exchange,提问作者Paras
相关产品推荐
相关产品推荐

