vue-electron 鼠标右键自定义菜单实现复制和粘贴功能
需求:根据产品经理所说,要在electron的应用上实现鼠标右键粘贴功能(实际上cv大法就能解决的事),为了照顾那些老用户,不懂得cv大法的,所以就做了这个鼠标右键复制粘贴的功能
看了一下网上的资料,只有一个react+electron的,我便写了一个vue+electron的,不过其实都差不多,只不过用法有点差异,我在粘贴这个功能上做了一点调整,react的那篇文章,好像有点只针对一个输入框去做处理了,不知道说的对不对,如果有错误请帮我指正,多多包涵
特别鸣谢:感谢那位写了react+electron自定义右键菜单的大佬,我是参考了你的文章,附上文章的链接: xuehuayu.cn/2020/04/29/…
效果:
1.实现右键自定义菜单
export function getContextMenu () {
// 监听contextmenu,实现自定义右键菜单
window.addEventListener('contextmenu', function (e) {
e.preventDefault()
let menu = new Menu()
//添加菜单功能, label: 菜单名称, accelerator:快捷键,click:点击方法
menu.append(new MenuItem({ label: '复制', accelerator: 'CommandOrControl+C', click: copyText }))
//添加菜单分割线
menu.append(new MenuItem({ type: 'separator' }))
//添加菜单功能
menu.append(new MenuItem({ label: '粘贴', accelerator: 'CommandOrControl+V', click: printText }))
menu.popup(remote.getCurrentWindow())
}, false)
}
复制代码
2.实现复制功能
export function getContextMenu () {
// 监听contextmenu,实现自定义右键菜单
...
function copyText () {
const str = getSelection() // 获取选中内容
clipboard.writeText(str) // 写入剪贴板
}
}
// 获取选中内容
function getSelection () {
var text = ''
if (window.getSelection) { // 除IE9以下 之外的浏览器
text = window.getSelection().toString()
} else if (document.selection && document.selection.type !== 'Control') { //IE9以下,可不考虑
text = document.selection.createRange().text
}
if (text) {
return text
}
}
复制代码
3.实现粘贴功能
// 获取剪贴版内容写入当前焦点元素中
function printText {
if (document.activeElement) {
const str = clipboard.readText() // 获取剪贴板内容
var ev = new Event('input', { bubbles: true});
ev.simulated = true;
document.activeElement.value = str; // 写入焦点元素
document.activeElement.dispatchEvent(ev);
// clipboard.clear() // 清空剪贴板,一般都不做清空,爱粘贴就粘贴,干嘛要粘贴完就清空呢
}
}
复制代码
4.受控组件粘贴后不能触发onChange事件的解决方法
问题截图:
// 之前差点因为这个问题放弃了这个功能,因为粘贴之后表面有值,但是实际上没有赋值,我打印了当前输入框没有赋值
// 解决方法
var ev = new Event('input', { bubbles: true});
ev.simulated = true;
document.activeElement.value = str; // 写入焦点元素
document.activeElement.dispatchEvent(ev);
复制代码
5.完整的代码
// contextMenu.js
import { remote, clipboard } from 'electron'
const { Menu, MenuItem } = remote
export function getContextMenu () {
//new一个菜单
// 监听contextmenu,实现自定义右键菜单
window.addEventListener('contextmenu', function (e) {
// 监听contextmenu,实现自定义右键菜单
window.addEventListener('contextmenu', function (e) {
e.preventDefault()
let menu = new Menu()
//添加菜单功能, label: 菜单名称, accelerator:快捷键,click:点击方法
menu.append(new MenuItem({ label: '复制', accelerator: 'CommandOrControl+C', click: copyText }))
//添加菜单分割线
menu.append(new MenuItem({ type: 'separator' }))
//添加菜单功能
menu.append(new MenuItem({ label: '粘贴', accelerator: 'CommandOrControl+V', click: printText }))
menu.popup(remote.getCurrentWindow())
}, false)
// 写入剪贴板方法
function copyText () {
const str = getSelection() // 获取选中内容
clipboard.writeText(str) // 写入剪贴板
}
// 获取剪贴版内容写入当前焦点元素中
function printText {
if (document.activeElement) {
const str = clipboard.readText() // 获取剪贴板内容
var ev = new Event('input', { bubbles: true});
ev.simulated = true;
document.activeElement.value = str; // 写入焦点元素
document.activeElement.dispatchEvent(ev);
// clipboard.clear() // 清空剪贴板,一般都不做清空,爱粘贴就粘贴,干嘛要粘贴完就清空呢
}
}
}
// 获取选中内容
function getSelection () {
var text = ''
if (window.getSelection) { // 除IE9以下 之外的浏览器
text = window.getSelection().toString()
} else if (document.selection && document.selection.type !== 'Control') { //IE9以下,可不考虑
text = document.selection.createRange().text
}
if (text) {
return text
}
}
复制代码
6.vue中的使用
我把代码放在了utils文件夹下面,新建了一个contextMenu.js文件
// main.js
// 初始化加载复制粘贴功能
import {getContextMenu} from './utils/contextMenu'
// 调用了一次,也许不用,可以使用个自执行函数,我偷了个懒
getContextMenu()
复制代码