electron-forge 搭建一个 electron 项 目
electron-forge 相当于 electron 的一个脚手架,可以让我们更方便的创建、运行、打包 electron 项目。
npm install -g electron-forge
electron-forge init my-new-app
cd my-new-app
npm start
主进程和渲染器进程
Electron 运行 package.json 的 main 脚本的进程被称为主进程。 在主进程中运行的脚 本通过创建 web 页面来展示用户界面。 一个 Electron 应用总是有且只有一个主进程。
由于 Electron 使用了 Chromium(谷歌浏览器)来展示 web 页面,所以 Chromium 的 多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它自己的渲染进程中。
主进程使用 BrowserWindow 实例创建页面。每个 BrowserWindow 实例都在自己的渲 染进程里运行页面。 当一个 BrowserWindow 实例被销毁后,相应的渲染进程也会被终止。
渲染进程中通过 Nodejs 读 取本地文件。
在普通的浏览器中, web 页面通常在一个沙盒环境中运行,不被允许去接触原生的资源。 然而 Electron 的用户在 Node.js 的 API 支持下可以在页面中和操作系统进行一些底层交互。
var fs = require('fs');
var content = document.getElementById('content');
var button = document.getElementById('button');
button.addEventListener('click', function(e) {
fs.readFile('package.json', 'utf8', function(err, data) {
content.innerHTML = data;
console.log(data);
});
});
Electron 模块
自定义软件顶部菜单、右键菜 单以及绑定快捷键
const remote = require('electron').remote;
const { Menu } = remote;
let template = [
{
label: '文件',
submenu: [
{
label: '新建窗口',
click: () => {
console.log('aaa');
}
},
{
label: '打开文件夹',
accelerator: 'ctrl+x',
click: () => {
console.log('bbb');
}
}
]
},
{
label: '编辑',
submenu: [
{
role: 'cut',
label: '剪切'
},
{
role: 'copy',
label: '复制'
}
]
}
];
var m = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(m);
var m = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(m);
window.addEventListener('contextmenu', e => {
e.preventDefault();
m.popup({ window: remote.getCurrentWindow() });
},false);
主进程与渲染进程之间的通信
Electron 主进程,和渲染进程的通信主要用到两个模块:ipcMain 和 ipcRenderer
ipcMain:当在主进程中使用时,它处理从渲染器进程(网页)发送出来的异步和同步信息, 当然也有可能从主进程向渲染进程发送消息。
ipcRenderer: 使用它提供的一些方法从渲染进程 (web 页面) 发送同步或异步的消息到主 进程。 也可以接收主进程回复的消息。
场景 1:渲染进程给主进程发送异步消息
//渲染进程
const { ipcRenderer } = require('electron')
ipcRenderer.send('msg',{name:'张三'}); //异步
//主进程
const { ipcMain } = require('electron');
ipcMain.on('msg',(event,arg) => {
})
场景 2:渲染进程给主进程发送异步消息,主进程接收到异步消息以后通知渲染进程:
//渲染进程
const { ipcRenderer } = require('electron')
ipcRenderer.send('msg',{name:'张三'}); //异步
//主进程
const { ipcMain } = require('electron');
ipcMain.on('msg',(event,arg) => {
event.sender.send('reply', 'pong');
})
//渲染进程
const { ipcRenderer } = require('electron')
ipcRenderer.on('reply', function(event, arg) {
console.log(arg); // "pong"
});
场景 3:渲染进程给主进程发送同步消息
//渲染进程
const { ipcRenderer } = require('electron')
const msg = ipcRenderer.sendSync('msg-a');
console.log(msg)
//主进程
ipcMain.on('msg-a',(event)=> {
event.returnValue = 'hello';
})
渲染进程与渲染进程之间的通信
Electron渲染进程通过localstorage给另一个渲染进程传值
通过 BrowserWindow 和 webContents 模块实现渲染进程和渲染进程的通信。(看代码)
shell 模块 在用户默认浏览器中打开 URL
let {shell} = require('electron');
shell.openExternal('https://github.com');
webview 标签
Webview 与 iframe 有点相似,但是与 iframe 不同,webview 和你的应用运行的是不同的进 程。它不拥有渲染进程的权限,并且应用和嵌入内容之间的交互全部都是异步的。因为这能 保证应用的安全性不受嵌入内容的影响
<webview id="webview" src="https://www.baidu.com" style="position:fixed; width:100%; height:100%">
</webview>
dialog 弹出框
错误框
dialog.showErrorBox('警告', '操作有误');
消息框
remote.dialog.showMessageBox({
type: 'info',
title: '提示信息',
message: '内容',
buttons: ['确定', '取消']
});
打开文件
dialog.showOpenDialog(
{
properties: ['openFile']
},
function(date) {
console.log(date);
}
);
保存文件
dialog.showSaveDialog(
{
title: 'save file',
filters: [
{ name: 'Images', extensions: ['jpg', 'png', 'gif'] },
{ name: 'Movies', extensions: ['mkv', 'avi', 'mp4'] },
{ name: 'Custom File Type', extensions: ['as'] },
{ name: 'All Files', extensions: ['*'] }
]
},
filename => {
console.log(filename);
}
);
系统托盘
设置系统托盘菜单和图标
const { Menu, Tray, BrowserWindow, app } = require('electron');
const path = require('path');
let iconTray = new Tray(path.join(__dirname, '../static/icon.png'));
let tpl = [
{
label: '设置',
click: function() {
console.log('setting');
}
},
{
label: '升级',
click: function() {
console.log('update');
}
},
{
label: '退出',
click: function() {
if (process.platform !== 'darwin') {
app.quit();
}
}
}
];
let trayTemplte = Menu.buildFromTemplate(tpl);
iconTray.setContextMenu(trayTemplte);
iconTray.setToolTip('地图');
全局快捷键
const { globalShortcut, app } = require('electron');
app.on('ready', function() {
globalShortcut.register('ctrl+e',function(){
console.log('ctrl +e')
})
console.log(globalShortcut.isRegistered('ctrl + e'))
});
app.on('will-quit',function(){
globalShortcut.unregister('ctrl + e')
})
electron-vue 的使用
Github 地址:github.com/SimulatedGR…
Electron-vue 文档:simulatedgreg.gitbooks.io/electron-vu…
# 安装 vue-cli 和 脚手架样板代码
npm install -g vue-cli
vue init simulatedgreg/electron-vue my-project
# 安装依赖并运行你的程序
cd my-project
yarn # 或者 npm install
yarn run dev # 或者 npm run dev