之前已经出了Electron系列第一篇,实现了简单的Hello World,感兴趣的小伙伴可以去翻看:juejin.cn/post/698026…
今天带来第二篇,继续讲讲Electron里面的其他功能用法。
Electron 的运行流程
先来看一个简单的流程
graph LR
Package.json --> 主进程文件 -->读取页面布局和演示 -->IPC执行任务和获取信息
Electron 的主进程和渲染进程
主进程
- package.json 中的入口文件即main 脚本的进程是主进程
- 一个Electron应用有且只有一个主进程
- 主进程可以进行 GUI 相关的原生 API 操作
渲染进程
- main.js主进程中创建渲染进程
- 使用BrowserWindow模块,创建和管理应用窗口。当一个BrowserWindow实例被销毁后,相应的渲染进程也被终止
- Electron使用了Chromium来展示web页面,所以Chromium的多进程架构也被使用到,每个 Electron 中的 web 页面运行在它自己的渲染进程中
- 主进程控制渲染进程,一个主进程可以控制多个渲染进程
了解了以上内容后,让我们来做一个简单的案例
简单示例
我们来做一个选择餐单的案例。在根目录下建立一个menu.txt的文件,然后写入对应的餐单名。
代码如下:
1.鱼香肉丝 2.小炒肉 3.回锅肉
有了这个文件,我们修改一下 main.js 文件,因为我们要使用 node 里的 fs 模块,所以在设置窗口时,增加全量使用 node.js.
var electron = require('electron')
var app = electron.app
var BrowserWindow = electron.BrowserWindow;
var mainWindow = null ;
app.on('ready',()=>{
mainWindow = new BrowserWindow({
width:500,
height:500,
webPreferences:{ nodeIntegration:true}
})
mainWindow.loadFile('index.html')
mainWindow.on('closed',()=>{
mainWindow = null
})
})
然后我们到 index.html 里写一个按钮,然后在按钮下方加一个div标签, 这个 DIV 用来作读取过来内容的容器.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, idivnitial-scale=1.0">
<title>Document</title>
</head>
<body>
<Button id="btn">餐单目录</Button><br/>
<div id="menu"></div>
</body>
</html>
然后我们可以单独新建一个 renderer 文件夹,名字意思是渲染进程中的操作. 文件夹建立完成后,在文件里新建 index.js 文件,然后再 index.html 页面里先进行引入.正常的js引入形式。最后展示完整的代码:
var fs = require('fs');
window.onload = function(){
var btn = this.document.querySelector('#btn')
var mybaby = this.document.querySelector('#menu')
btn.onclick = function(){
fs.readFile('xiaojiejie.txt',(err,data)=>{
mybaby.innerHTML = data
})
}
}
最后,执行electron .吗,命令,就可以跳出界面,看到目录了。
Electron Remote 模块
Electron 有主进程和渲染进程, Electron 的 API 方法和模块也是分别可以在主进程和渲染进程中使用。接下来我们就可以使用 Electron Remote 解决在渲染和主进程间的通讯。
在项目根目录下,新建一个 windowDemo.html 文件,然后快速生成 html 的基本结构,编写一个按钮,引入渲染的 js 页面。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<Button id="btn">打开新的窗口</Button><br/>
<script src="renderer/windowDemo.js"></script>
</body>
</html>
在 render 文件夹下,新建一个 windowDemo.js 文件,然后编写如下代码:
const btn = this.document.querySelector('#btn')
const BrowserWindow =require('electron').remote.BrowserWindow
window.onload = function(){
btn.onclick = ()=>{
newWin = new BrowserWindow({
width:500,
height:500,
})
newWin.loadFile('menuList.html')
newWin.on('close',()=>{win=null})
}
}
顺便新建menuLIst.html页面:
const btn = this.document.querySelector('#btn')
const BrowserWindow =require('electron').remote.BrowserWindow
window.onload = function(){
btn.onclick = ()=>{
newWin = new BrowserWindow({
width:500,
height:500,
})
newWin.loadFile('menuLIst.html')
newWin.on('close',()=>{win=null})
}
}
然后我们在终端中运行 electron ., 如果一切正常,就可以顺利打开一个新的窗口,这个窗口可以顺利打开主要的功劳就是 electron remote。它让我们有了很多 pc 端的原生能力,这就是简单的electron remote实现后续更为复杂的功能请大家自行研究了。
Electron 创建菜单
之前也创建了好几个菜品,不过那只是展示,这次我们来实现Electron 中使用 Menu 来完成菜单的创建
- 编写菜单模板 新建一个menuList.js文件:
const { Menu } = require('electron')
var template = [
{
label:'江南之乡',
submenu:[
{label:'西湖醋鱼'},
{label:'龙井虾仁'}
]
},
{
label:'川菜馆',
submenu:[
{label:'小炒肉'},
{label:'回锅肉'}
]
}
]
var m = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(m)
然后再打开主进程 main.js 文件,在 ready 生命周期中,直接加入下面的代码,就可以实现自定义菜单了
require('./main/menuList.js')
- 使用菜单打开新窗口
在菜单中加入
click事件,代码如下:
const { Menu ,BrowserWindow} = require('electron')
var template = [
{
label:'江南之乡',
submenu:[
{
label:'西湖醋鱼',
//主要代码--------------start
click:()=>{
win = new BrowserWindow({
width:500,
height:500,
webPreferences:{ nodeIntegration:true}
})
win.loadFile('menuList.html')
win.on('closed',()=>{
win = null
})
}
//主要代码----------------end
},
{label:'龙井虾仁'}
]
},
{
label:'川菜馆',
submenu:[
{label:'小炒肉'},
{label:'回锅肉'}
]
}
]
var m = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(m)
最后打开终端输入 electron . 之后,就可以看到效果了
Electron 制作右键菜单
上面学习了如何设置顶部菜单,我们也作了一个菜单的小案例,这次我们继续学习如何实现右键功能。
- 菜单快捷键绑定
绑定快捷键的属性是
accelerator属性,比如我们新打开一个窗口。
accelerator:`ctrl+n`
全部代码还是上面的代码,就不粘贴了。写完代码后,在终端中输入 electron . 运行程序,再用快捷键 ctrl+n 就可以新建一个页面了。这就实现了新建页面的方法。
- 创建右键菜单
右键菜单的响应事件是写在渲染进程中的,也就是写在
index.html中的,所以要是使用,就用到到remote模块进行操作了。
先来看看右键的相应事件,我们打开 render 文件夹,然后打开 windowDemo.js 文件,编写一个右键菜单的监听事件,代码如下:
window.addEventListener('contextmenu',function(){
alert(123);
})
使用remote
const { remote} = require('electron')
var rigthTemplate = [
{label:'粘贴'},
{label:'复制'}
]
var m = remote.Menu.buildFromTemplate(rigthTemplate)
window.addEventListener('contextmenu',function(e){
//阻止当前窗口默认事件
e.preventDefault();
//把菜单模板添加到右键菜单
m.popup({window:remote.getCurrentWindow()})
})
最后我们可以在终端中输入 electron . 打开程序进行测试右键菜单功能。
- 程序打开调试模式 我们可以继续添加一个调试模式的菜单:
mainWindow.webContents.openDevTools()
全部代码如下:
var electron = require('electron')
var app = electron.app
var BrowserWindow = electron.BrowserWindow;
var mainWindow = null ;
app.on('ready',()=>{
mainWindow = new BrowserWindow({
width:500,
height:500,
webPreferences:{ nodeIntegration:true}
})
mainWindow.webContents.openDevTools()
require('./main/menuList.js')
mainWindow.loadFile('windowDemo.html')
mainWindow.on('closed',()=>{
mainWindow = null
})
})
这样就实现了打开窗口,直接进入调试模式,极大的提高了调试效率.
Electron 中通过链接打开浏览器
我们知道在渲染进程中默认加入一个 <a> 标签,进行跳转默认是直接在窗口中打开,而不是在浏览器中打开的,如果我们想在默认浏览器中打开,需要怎么操作?那就是electron shell
- 默认打开示例
我们先来看一下,在 electron 中默认打开一个链接是什么样的,在项目根目录,新建一个
demo.html文件,编写一个<a>标签,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>
<a href="https://www.baidu.com"></a>
</h1>
</body>
</html>
- 使用Shell在浏览器中打开
在
<a>标签中加入 id
<a id="hrefs" href="https://www.baidu.com"></a>
在 render 文件夹下,新建一个 demo1.js 文件,先在文件首页中引入 shell, 然后编写响应事件 click。
var { shell } = require('electron')
var hrefs = document.querySelector('#hrefs')
aHref.onclick = function(e){
e.preventDefault()
var href = this.getAttribute('href')
shell.openExternal(href)
}
在html 中引入 demo1.js 文件
<script src="./renderer/demo1.js"></script>
这样就实现了在浏览器中打开链接的操作了。
结语:本文是Electron系列第二篇,由于事情比较多,没有按时的学习并输送文章,不过只要有时间,还是会慢慢学习总结的。我们的学习之路还没有结束,Electron里面的对话框操作、断网提醒、消息通知、剪切板等,都会在后期文章中陆续出现。