最近做公司项目,由于是个聊天项目,有用到上下文菜单的需求(右键删除聊天记录等),网上方法参差不齐,整理了下自己的思路。
什么是上下文菜单呢,其实就是右键菜单,右击某块区域弹出的菜单你们城里人说话就是不一样
渲染进程实现
首先在需要实现的页面引入必要的组件,上下文菜单的实现需要Menu模块
诶注意,别直接傻傻引进来了,渲染进程是不能使用 electron 组件的,这个时候就需要用到remote
remote模块,说白了就是让你在渲染进程中也能使用主进程模块的东西,引入代码如下
import { remote } from 'electron'const { Menu } = remote有两种实现方法,先说个人认为比较麻烦但好理解的一种
创建一个船新的空Menu
此方法需要引入MenuItem,我们把上面的引入稍微修改一下
const { Menu, MenuItem } = remote步骤为:
- 创建一个船新的空
Menu - 将数个
MenuItem塞到Menu里 - 最后通过
popup()控制Menu显示的显示popup()内可以传递一个作用区域(BrowserWindow对象),其他参数见下图(来自官方文档Menu篇)
代码如下
// 创建新的空菜单const menu = new Menu()// 添加第一个子菜单menu.append(new MenuItem({ label: 'item1', click: function() { // 执行方法 }}))// 添加第二个子菜单(子菜单)menu.append(new MenuItem({ label: 'item2', submenu: [{ label: 'item2-1', click: () => { // 执行方法 } }]}))// 添加第三个子菜单// menu.append(...)// 把Menu展示出来menu.popup(remote.getCurrentWindow())比较好懂对不对?无非就是创建个空菜单,然后不停的往里一条一条的塞东西,但,岂不是太麻烦了点?
直接通过对象创建Menu
这个就相对省事了,创建一个模板对象, 然后使用buildFromTemplate()直接通过模板对象创建一个Menu,再通过popup()控制Menu显示的显示即可,还不需要引入 MenuItem,代码如下
// 创建模板对象const contextTemplate = [{ label: 'item1', click: () => { // 执行方法 }},{ label: 'item2', submenu: [{ label: 'item2-1', click: () => { // 执行方法 } }]}]// 使用模板对象创建Menuconst contextMenu = Menu.buildFromTemplate(contextTemplate)// 把Menu展示出来menu.popup(remote.getCurrentWindow())逻辑清晰了不少吧?个人更喜欢用第二种方法,当然还是各取所需啦,而且第二种方法创建的contextMenu也可以使用append()额外添加新的MenuItem的,不冲突
*更多的MenuItem属性可以参考官方文档
主进程实现
当然如果嫌麻烦或者不想在渲染进程实现的话,主进程也是可以的(即background.js),主线程中不需要使用remote,可以直接从electron中引入 Menu、MenuItem,需要使用ipcMain进程通讯模块来通知渲染线程,创建方法省略,和上面没什么区别,大体说一下进程通讯
主进程内
// 引入进程通讯模块import { ipcMain } from 'electron'// 启动监听事件ipcMain.on('show-context-menu', (e) => { // win 为触发该事件所在的窗口 const win = BrowserWindow.fromWebContents(e.sender) menu.popup(win)})渲染进程内
// 引入进程通讯模块import { ipcRenderer } from 'electron'// 触发监听事件ipcRenderer.send('show-context-menu')调用
好像还没说怎么调用呢,当然是那个右键触发打开上下文菜单啦不过这个应该不用说吧
右键事件为contextmenu,vue中可以直接在标签上@contextmenu.prevent=""即可
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时