Skip to main content

菜单

🌐 Menus

Electron 的 Menu 类提供了一种标准化的方法,用于在整个应用中创建跨平台的原生菜单。

🌐 Electron's Menu class provides a standardized way to create cross-platform native menus throughout your application.

Electron 中可用的菜单

🌐 Available menus in Electron

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

🌐 The same menu API is used for multiple use cases:

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

要了解有关你可以创建的各种本地菜单以及如何指定快捷键的更多信息,请参阅本节中的各个指南:

🌐 To learn more about the various kinds of native menus you can create and how to specify keyboard shortcuts, see the individual guides in this section:

构建菜单

🌐 Building menus

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

🌐 Each Menu instance is composed of an array of MenuItem objects accessible via the menu.items instance property. Menus can be nested by setting the item.submenu property to another menu.

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

🌐 There are two ways to build a menu: either by directly calling menu.append or by using the static Menu.buildFromTemplate helper function.

这个辅助函数通过允许你将一组 MenuItem 构造函数选项(或已实例化的 MenuItem 实例)放在一个数组中传递,而不是在每次函数调用中单独追加每个项目,从而减少了样板代码。

🌐 The helper function reduces boilerplate by allowing you to pass a collection of MenuItem constructor options (or instantiated MenuItem instances) in a single array rather than having to append each item in a separate function call.

下面是一个最小应用菜单的示例:

🌐 Below is an example of a minimal application menu:

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

类型

🌐 Types

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

🌐 A menu item's type grants it a particular appearance and functionality. Some types are automatically assigned based on other constructor options:

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

其他可用类型(指定后)会为菜单项赋予特殊的附加属性:

🌐 Other available types, when specified, give special additional properties to the menu item:

  • checkbox - 每当点击菜单项时切换 checked 属性
  • radio - 切换 checked 属性,并关闭所有相邻 radio 项的该属性
  • palette - 创建一个 Palette 子菜单,将项目水平排列(适用于 macOS 14 及以上版本)
  • header - 创建一个部分标题,可以使用标签进行分组(macOS 14 及更高版本可用)
tip

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

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

角色

🌐 Roles

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

🌐 Roles give normal type menu items predefined behaviors.

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

🌐 We recommend specifying the role attribute for any menu item that matches a standard role rather than trying to manually implement the behavior in a click function. The built-in role behavior will give the best native experience.

使用 role 时,labelaccelerator 的值是可选的,并且会默认采用各个平台的适当值。

🌐 The label and accelerator values are optional when using a role and will default to appropriate values for each platform.

tip

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

编辑角色

🌐 Edit roles

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

窗口角色

🌐 Window roles

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

默认菜单角色

🌐 Default menu roles

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

macOS 独有角色

🌐 macOS-only roles

macOS 提供了许多特定于平台的菜单角色。许多这些角色映射到底层的 AppKit API。

🌐 macOS has a number of platform-specific menu roles available. Many of these map to underlying AppKit APIs.

应用管理角色

🌐 App management roles

编辑角色

🌐 Edit roles

语音角色

🌐 Speech roles

原生标签角色

🌐 Native tab roles

默认菜单角色

🌐 Default menu roles

  • appMenu - 整个默认“应用”菜单(关于、本地服务等)
  • services - 子菜单是一个“服务”菜单。
  • window - 子菜单是“窗口”菜单。
  • help - 子菜单是“帮助”菜单。
其他菜单角色

🌐 Other menu roles

info

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

加速器

🌐 Accelerators

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

🌐 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

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

🌐 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 - 在具有指定 ID 的项目之前插入此项目。如果引用的项目不存在,该项目将被插入到菜单的末尾。还意味着相关的菜单项应与该项目放在同一个“组”中。
  • after - 在指定ID的项目之后插入此项目。如果所引用的项目不存在,该项目将被插入到菜单的末尾。同时,这也意味着相关的菜单项应与该项目放在同一“组”中。
  • beforeGroupContaining - 为单个上下文菜单提供一种方式,以在具有指定 ID 的项目的包含组之前声明其包含组的位置。
  • afterGroupContaining - 为单个上下文菜单提供一种方式,以在具有指定 ID 的项目的包含组之后声明其包含组的位置。

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

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

示例

🌐 Examples

模板:

🌐 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

为了在菜单中添加视觉辅助,你可以使用 icon 属性为各个 MenuItem 实例分配图片。

🌐 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
})

子标签 macOS

🌐 Sublabels macOS

你可以在 macOS 14.4 及以上版本中,使用 sublabel 选项为菜单项添加子标签(也称为字幕)。

🌐 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...') }
})

工具提示_macOS_

🌐 Tooltips macOS

工具提示是当你将鼠标悬停在菜单项上时出现的信息指示。你可以在 macOS 上使用 toolTip 选项设置菜单项的工具提示。

🌐 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'
})