跳转到主内容

菜单

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

Electron 中的可用菜单

同一个 Menu API 用于多个场景:

  • 应用菜单 是您应用程序的顶层菜单。 每个应用同时只能有一个应用菜单。
  • 上下文菜单会在用户右键应用界面上的特定区域时被触发。
  • 托盘菜单是一个特殊的上下文菜单,会在右键应用的 Tray 实例时被触发。
  • 在 macOS 上,Dock 菜单是一个特殊的上下文菜单,会在右键系统 Dock 中应用图标时被触发。

想了解能够创建的各种类型的本地菜单,以及如何指定键盘快捷方式,可以查看本节中的单独指南:

构建菜单

每个 Menu 实例由一个通过 menu.items 实例属性访问的 MenuItem 对象数组组成。 菜单可以通过把另一个菜单设置到 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)
info

所有菜单项(除了 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' } // 不会被其它项影响
]

角色

角色给 normal 类型菜单项赋予预先定义的行为。

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

当使用 role 时,labelaccelerator 是可选的,并会为每个平台设置合适的默认值。

提示

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

编辑角色

  • undo
  • redo
  • cut
  • copy
  • paste
  • pasteAndMatchStyle
  • selectAll
  • delete

窗口角色

  • 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 - The submenu is [share menu][ShareMenu]. The sharingItem property must also be set to indicate the item to share.
info

When specifying a role on macOS, label and accelerator are the only options that will affect the menu item. 所有其它选项都将被忽略。

加速器

The accelerator property allows you to define accelerator strings to map menu items to keyboard shortcuts. For more details, see the Keyboard Shortcuts guide.

Advanced configuration

Programmatic item positioning

You can make use of the before, after, beforeGroupContaining, afterGroupContaining and id attributes to control how menu items will be placed when building a menu with Menu.buildFromTemplate.

  • before - Inserts this item before the item with the specified id. If the referenced item doesn't exist, the item will be inserted at the end of the menu. 这还意味着,菜单项应该被放置在与引用项相同的组中。
  • after - Inserts this item after the item with the specified id. If the referenced item doesn't exist, the item will be inserted at the end of the menu. 这还意味着,菜单项应该被放置在与引用项相同的组中。
  • beforeGroupContaining - Provides a means for a single context menu to declare the placement of their containing group before the containing group of the item with the specified id.
  • afterGroupContaining - Provides a means for a single context menu to declare the placement of their containing group after the containing group of the item with the specified id.

By default, items will be inserted in the order they exist in the template unless one of the specified positioning keywords is used.

示例

Template:

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

Menu:

- one
- two
- three
- four

Template:

[
{ 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

Template:

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

Menu:

- ---
- three
- two
- one

Icons

To add visual aid to your menus, you can use the icon property to assign images to individual MenuItem instances.

Adding a little green circle to a menu item
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
})

Sublabels macOS

You can add sublabels (also known as subtitles) to menu items using the sublabel option on macOS 14.4 and above.

Adding descriptions via 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...') }
})

Tooltips macOS

Tooltips are informational indicators that appear when you hover over a menu item. You can set menu item tooltips on macOS using the toolTip option.

Adding additional information via tooltip
const { MenuItem } = require('electron/main')

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