跳转到主要内容

菜单

Electron 的 Menu 类提供了一种标准化的方式,可以在您的应用程序中创建跨平台的原生菜单。

Electron 中可用的菜单

相同的菜单 API 用于多种用例

  • 应用程序菜单是您应用程序的顶级菜单。每个应用程序一次只有一个应用程序菜单。
  • 上下文菜单由用户在右键单击应用程序界面的某个部分时触发。
  • 托盘菜单是一种特殊的上下文菜单,当右键单击应用程序的 Tray 实例时触发。
  • 在 macOS 上,Dock 菜单是一种特殊的上下文菜单,当右键单击系统 Dock 中的应用程序图标时触发。

要了解有关您可以创建的各种类型的原生菜单以及如何指定键盘快捷键,请参阅本节中的各个指南

构建菜单

每个 Menu 实例由一个 MenuItem 对象数组组成,可以通过 menu.items 实例属性访问。可以通过将 item.submenu 属性设置为另一个菜单来嵌套菜单。

有两种方法可以构建菜单:可以直接调用 menu.append,或者使用静态 Menu.buildFromTemplate 辅助函数。

辅助函数通过允许您在一个数组中传递一组 MenuItem 构造函数选项(或实例化后的 MenuItem 实例),从而减少了样板代码,而无需在单独的函数调用中追加每个项目。

以下是一个最小应用程序菜单的示例

menu.js
const submenu = new Menu()
submenu.append(new MenuItem({ label: 'Hello' }))
submenu.append(new MenuItem({ type: 'separator' }))
submenu.append(new MenuItem({ label: 'Electron', type: 'checkbox', checked: true }))
const menu = new Menu()
menu.append(new MenuItem({ label: 'Menu', submenu }))
Menu.setApplicationMenu(menu)
信息

所有菜单项(separator 类型除外)都必须具有标签。标签可以手动使用 label 属性定义,也可以从项目的 role 继承。

类型

菜单项的类型赋予其特定的外观和功能。有些类型是根据其他构造函数选项自动分配的

  • 默认情况下,菜单项具有 normal 类型。
  • 包含 submenu 属性的菜单项将被分配 submenu 类型。

其他可用的类型(在指定时)会为菜单项提供特殊的附加属性

  • checkbox - 每次单击菜单项时切换 checked 属性
  • radio - 切换 checked 属性,并关闭所有相邻 radio 项的该属性
  • palette - 创建一个 Palette 子菜单,水平对齐项目(在 macOS 14 及更高版本上可用)
  • header - 创建一个部分标题,可以使用标签传达分组(在 macOS 14 及更高版本上可用)
提示

相邻的 radio 项位于同一级别的子菜单中,并且不被分隔符分隔。

[
{ type: 'radio', label: 'Adjacent 1' },
{ type: 'radio', label: 'Adjacent 2' },
{ type: 'separator' },
{ type: 'radio', label: 'Non-adjacent' } // unaffected by the others
]

角色

角色为 normal 类型的菜单项提供预定义的行为。

我们建议为与标准角色匹配的任何菜单项指定 role 属性,而不是尝试在 click 函数中手动实现该行为。内置的 role 行为将提供最佳的原生体验。

在使用 role 时,labelaccelerator 值是可选的,并且将默认为每个平台的适当值。

提示

角色字符串不区分大小写。例如,toggleDevToolstoggledevtoolsTOGGLEDEVTOOLS 在定义菜单项时都是等效的角色。

编辑角色

  • 撤销
  • 重做
  • 剪切
  • 复制
  • 粘贴
  • 粘贴并匹配样式
  • 全选
  • 删除

窗口角色

  • about - 触发原生关于面板(Windows 上的自定义消息框,不提供自己的)
  • minimize - 最小化当前窗口。
  • close - 关闭当前窗口。
  • quit - 退出应用程序。
  • reload - 重新加载当前窗口。
  • forceReload - 忽略缓存重新加载当前窗口。
  • toggleDevTools - 切换当前窗口中的开发者工具。
  • togglefullscreen - 切换当前窗口的全屏模式。
  • resetZoom - 将聚焦页面的缩放级别重置为原始大小。
  • zoomIn - 将聚焦页面放大 10%。
  • zoomOut - 将聚焦页面缩小 10%。
  • toggleSpellChecker - 启用/禁用内置拼写检查器。

默认菜单角色

  • fileMenu - 子菜单是“文件”菜单(关闭/退出)
  • editMenu - 子菜单是“编辑”菜单(撤销、复制等)
  • viewMenu - 子菜单是“视图”菜单(重新加载、切换开发者工具等)
  • windowMenu - 子菜单是“窗口”菜单(最小化、缩放等)

仅 macOS 角色

macOS 有许多特定于平台的菜单角色可用。其中许多映射到底层的 AppKit API。

应用程序管理角色
编辑角色
语音角色
原生选项卡角色
默认菜单角色
  • appMenu - 整个默认“应用程序”菜单(关于、服务等)
  • services - 子菜单是“服务”菜单。
  • window - 子菜单是“窗口”菜单。
  • help - 子菜单是“帮助”菜单。
其他菜单角色
  • recentDocuments - 子菜单是“打开最近”菜单。
  • clearRecentDocuments - 映射到 clearRecentDocuments 操作。
  • shareMenu - 子菜单是 [分享菜单][ShareMenu]。还必须设置 sharingItem 属性,以指示要分享的项目。
信息

在 macOS 上指定 role 时,labelaccelerator 是唯一会影响菜单项的选项。所有其他选项都将被忽略。

加速器

accelerator 属性允许您定义加速器字符串,以将菜单项映射到键盘快捷键。有关更多详细信息,请参阅 键盘快捷键 指南。

高级配置

程序化菜单项定位

您可以使用 beforeafterbeforeGroupContainingafterGroupContainingid 属性来控制在使用 Menu.buildFromTemplate 构建菜单时菜单项的放置方式。

  • before - 将此项插入到具有指定 id 的项之前。如果引用的项不存在,则该项将插入到菜单的末尾。同时意味着所讨论的菜单项应放置在与该项相同的“组”中。
  • after - 将此项插入到具有指定 id 的项之后。如果引用的项不存在,则该项将插入到菜单的末尾。同时意味着所讨论的菜单项应放置在与该项相同的“组”中。
  • beforeGroupContaining - 提供了一种方法,允许单个上下文菜单声明其包含组的放置位置在其包含指定 id 的项的组之前。
  • afterGroupContaining - 提供了一种方法,允许单个上下文菜单声明其包含组的放置位置在其包含指定 id 的项的组之后。

默认情况下,项目将按照它们在模板中存在的顺序插入,除非使用了指定的定位关键字之一。

示例

模板

[
{ id: '1', label: 'one' },
{ id: '2', label: 'two' },
{ id: '3', label: 'three' },
{ id: '4', label: 'four' }
]

Menu

- one
- two
- three
- four

模板

[
{ id: '1', label: 'one' },
{ type: 'separator' },
{ id: '3', label: 'three', beforeGroupContaining: ['1'] },
{ id: '4', label: 'four', afterGroupContaining: ['2'] },
{ type: 'separator' },
{ id: '2', label: 'two' }
]

Menu

- three
- four
- ---
- one
- ---
- two

模板

[
{ id: '1', label: 'one', after: ['3'] },
{ id: '2', label: 'two', before: ['1'] },
{ id: '3', label: 'three' }
]

Menu

- ---
- three
- two
- one

图标

为了给您的菜单提供视觉辅助,您可以使用 icon 属性将图像分配给单个 MenuItem 实例。

为菜单项添加一个小绿圈
const { nativeImage } = require('electron/common')
const { MenuItem } = require('electron/main')

const green = nativeImage.createFromDataURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACOSURBVHgBpZLRDYAgEEOrEzgCozCCGzkCbKArOIlugJvgoRAUNcLRpvGH19TkgFQWkqIohhK8UEaKwKcsOg/+WR1vX+AlA74u6q4FqgCOSzwsGHCwbKliAF89Cv89tWmOT4VaVMoVbOBrdQUz+FrD6XItzh4LzYB1HFJ9yrEkZ4l+wvcid9pTssh4UKbPd+4vED2Nd54iAAAAAElFTkSuQmCC')

const item = new MenuItem({
label: 'Green Circle',
icon: green
})

副标签 macOS

您可以使用 macOS 14.4 及更高版本上的 sublabel 选项将副标签(也称为 副标题)添加到菜单项。

通过副标签添加描述
const { MenuItem } = require('electron/main')

const item = new MenuItem({
label: 'Log Message',
sublabel: 'This will use the console.log utility',
click: () => { console.log('Logging via menu...') }
})

工具提示 macOS

工具提示是在您悬停在菜单项上时显示的提示性指示器。您可以使用 toolTip 选项在 macOS 上设置菜单项工具提示。

通过工具提示添加额外信息
const { MenuItem } = require('electron/main')

const item = new MenuItem({
label: 'Hover Over Me',
toolTip: 'This is additional info that appears on hover'
})