Skip to content
On this page

electron-context-menu

一个用于在 Electron 应用程序中添加上下文菜单的工具

安装

bash
pnpm add electron-context-menu

基础配置

主进程配置

ts
import { app, BrowserWindow } from 'electron'
import contextMenu from 'electron-context-menu'

// 配置默认上下文菜单
contextMenu({
  // 显示默认菜单项
  showLookUpSelection: true,
  showSearchWithGoogle: true,
  showCopyImage: true,
  showSaveImageAs: true,
  showSaveVideoAs: true,
  showCopyVideoAddress: true,
  showCopyLink: true,
  showSaveLinkAs: true,
  showInspectElement: true,
})

app.whenReady().then(() => {
  const mainWindow = new BrowserWindow({
    width: 900,
    height: 670,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
    },
  })
})

使用示例

自定义菜单项

ts
import contextMenu from 'electron-context-menu'

contextMenu({
  menu: (actions, props, browserWindow, dictionarySuggestions) => [
    // 添加自定义菜单项
    {
      label: '自定义操作',
      click: () => {
        console.log('点击了自定义菜单项')
      },
    },
    // 添加分隔线
    { type: 'separator' },
    // 条件显示菜单项
    props.mediaType === 'image' && {
      label: '保存图片',
      click: () => actions.saveImage(),
    },
    // 使用默认操作
    actions.copy(),
    actions.paste(),
  ],
})

窗口特定菜单

ts
import contextMenu from 'electron-context-menu'

// 为特定窗口配置上下文菜单
const mainWindow = new BrowserWindow()
const childWindow = new BrowserWindow()

// 主窗口菜单
contextMenu({
  window: mainWindow,
  menu: (actions) => [
    actions.copy(),
    actions.paste(),
    {
      label: '主窗口特有功能',
      click: () => console.log('主窗口操作'),
    },
  ],
})

// 子窗口菜单
contextMenu({
  window: childWindow,
  menu: (actions) => [
    actions.copy(),
    {
      label: '子窗口特有功能',
      click: () => console.log('子窗口操作'),
    },
  ],
})

高级配置

ts
import { app, BrowserWindow } from 'electron'
import contextMenu from 'electron-context-menu'

// 高级菜单配置
contextMenu({
  // 自定义菜单显示逻辑
  showMenu: (event, props) => {
    // 根据条件决定是否显示菜单
    if (props.isEditable) {
      return true
    }
    return false
  },

  // 自定义菜单项
  menu: (actions, props, browserWindow) => [
    // 动态生成菜单项
    ...['选项1', '选项2', '选项3'].map((label) => ({
      label,
      click: () => console.log(`点击了${label}`),
    })),

    { type: 'separator' },

    // 带快捷键的菜单项
    {
      label: '刷新',
      accelerator: 'CmdOrCtrl+R',
      click: () => browserWindow.reload(),
    },

    // 带子菜单的菜单项
    {
      label: '更多操作',
      submenu: [
        {
          label: '子操作1',
          click: () => console.log('子操作1'),
        },
        {
          label: '子操作2',
          click: () => console.log('子操作2'),
        },
      ],
    },

    // 根据条件显示不同菜单项
    props.linkURL && [
      { type: 'separator' },
      actions.copyLink(),
      {
        label: '在浏览器中打开',
        click: () => shell.openExternal(props.linkURL),
      },
    ],

    // 自定义字典建议
    props.selectionText &&
      props.dictionarySuggestions?.length > 0 && [
        { type: 'separator' },
        ...props.dictionarySuggestions.map((suggestion) => ({
          label: suggestion,
          click: () => {
            browserWindow.webContents.replaceMisspelling(suggestion)
          },
        })),
      ],
  ],

  // 自定义样式
  style: {
    menu: {
      backgroundColor: '#2E2E2E',
      borderRadius: '8px',
    },
    menuItem: {
      color: '#FFFFFF',
    },
    separator: {
      borderColor: '#404040',
    },
  },
})

app.whenReady().then(() => {
  const mainWindow = new BrowserWindow({
    width: 900,
    height: 670,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
    },
  })
})

要保持清醒 永远不抱有意外的幻想 凭空的期待最要命