Skip to content

原生菜单

原生菜单模板

js
const { app, shell, ipcMain } = require('electron')

let template = [{
		label: '文件',
		submenu: [{
			label: '新建',
			accelerator: 'CmdOrCtrl+N',
			click: (menuItem, browserWindow, event) => { // 自定义触发事件
				browserWindow.webContents.send('create-new-file')
			}
		}, {
			label: '保存',
			accelerator: 'CmdOrCtrl+S',
			click: (menuItem, browserWindow, event) => {
				browserWindow.webContents.send('save-edit-file')
			}
		}]
	},
	{
		label: '编辑',
		submenu: [{
			label: '撤销',
			accelerator: 'CmdOrCtrl+Z',
			role: 'undo' // 系统原生自带事件
		}, {
			label: '重做',
			accelerator: 'Shift+CmdOrCtrl+Z',
			role: 'redo'
		}, {
			type: 'separator'
		}, {
			label: '剪切',
			accelerator: 'CmdOrCtrl+X',
			role: 'cut'
		}, {
			label: '复制',
			accelerator: 'CmdOrCtrl+C',
			role: 'copy'
		}, {
			label: '粘贴',
			accelerator: 'CmdOrCtrl+V',
			role: 'paste'
		}, {
			label: '全选',
			accelerator: 'CmdOrCtrl+A',
			role: 'selectall'
		}]
	},
	{
		label: '视图',
		submenu: [{
				label: '刷新当前页面',
				accelerator: 'CmdOrCtrl+R',
				click: (item, focusedWindow) => {
					if (focusedWindow)
						focusedWindow.reload();
				}
			},
			{
				label: '切换全屏幕',
				accelerator: (() => {
					if (process.platform === 'darwin')
						return 'Ctrl+Command+F';
					else
						return 'F11';
				})(),
				click: (item, focusedWindow) => {
					if (focusedWindow)
						focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
				}
			},
			{
				label: '切换开发者工具',
				accelerator: (function () {
					if (process.platform === 'darwin')
						return 'Alt+Command+I';
					else
						return 'Ctrl+Shift+I';
				})(),
				click: (item, focusedWindow) => {
					if (focusedWindow)
						focusedWindow.toggleDevTools();
				}
			},
		]
	},
	{
		label: '窗口',
		role: 'window',
		submenu: [{
			label: '最小化',
			accelerator: 'CmdOrCtrl+M',
			role: 'minimize'
		}, {
			label: '关闭',
			accelerator: 'CmdOrCtrl+W',
			role: 'close'
		}]
	},
	{
		label: '帮助',
		role: 'help',
		submenu: [{
			label: '学习更多',
			click: () => {
				shell.openExternal('http://electron.atom.io')
			}
		}, ]
	},
]

// mac 系统
if (process.platform === 'darwin') {
	const name = app.getName()
	template.unshift({
		label: name,
		submenu: [{
			label: `关于 ${name}`,
			role: 'about'
		}, {
			type: 'separator'
		}, {
			label: '设置',
			accelerator: 'Command+,',
			click: () => {
				ipcMain.emit('open-settings-window')
			}
		}, {
			label: '服务',
			role: 'services',
			submenu: []
		}, {
			type: 'separator'
		}, {
			label: `隐藏 ${name}`,
			accelerator: 'Command+H',
			role: 'hide'
		}, {
			label: '隐藏其它',
			accelerator: 'Command+Alt+H',
			role: 'hideothers'
		}, {
			label: '显示全部',
			role: 'unhide'
		}, {
			type: 'separator'
		}, {
			label: '退出',
			accelerator: 'Command+Q',
			click: () => {
				app.quit()
			}
		}]
	})
} else { // window 系统,设置
	template[0].submenu.push({
		label: '设置',
		accelerator: 'Ctrl+,',
		click: () => {
			ipcMain.emit('open-settings-window')
		}
	})
}

module.exports = template

在 main.js 中创建原生菜单

js
const { app, Menu } = require('electron')
const menuTemplate = require('./src/menuTemplate')

app.on('ready', () => {
  	let menu = Menu.buildFromTemplate(menuTemplate)
	Menu.setApplicationMenu(menu)  
})

自定义 hooks

  • 用于触发自定义事件

封装

typescript
import { useEffect } from 'react'
const { ipcRenderer } = window.require('electron')

// key:上面模板文件的 browserWindow.webContents.send 的名字
interface IKeyCallbackMap {
    [key: string]: () => void;
}

const useIPCRenderer = (keyCallbackMap: IKeyCallbackMap) => {
    useEffect(() => {
        Object.keys(keyCallbackMap).forEach(key => {
            ipcRenderer.on(key, keyCallbackMap[key])
        })
        return () => {
            Object.keys(keyCallbackMap).forEach(key => {
                ipcRenderer.removeListener(key, keyCallbackMap[key])
            })
        }
    })
}

export default useIPCRenderer

使用例子

js
import useIPCRenderer from './hooks/useIPCRenderer'
useIPCRenderer({
    'create-new-file': createFile,
    'save-edit-file': saveFile
})