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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:52:12