Electron

一直觉得直接使用前端技术来构建桌面应用或手机应用挺好玩的,因为做手机应用要装很多东西太麻烦,以后再学,现在就先学一下Electron吧。

安装

之前看到网上很多都是npm install electron-prebuilt -g,然后发现自己装的时候出错了,不知是不是教程太旧了。现在的是

1
cnpm install electron -g

(cnpm 淘宝镜像)

简单应用

安装完后,我们可以自己搭个简单的项目了。
目录结构如下:

然后自己对每个文件做一些简单修改。

  • index.html
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>An electron app</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
  • main.js

main.js是整个程序的入口文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const { app, BrowserWindow } = require('electron');

let win;

function createWindow() {
// 创建窗口并加载页面
win = new BrowserWindow({ width: 800, height: 600 });
win.loadURL(`file://${__dirname}/index.html`);

// 窗口关闭的监听
win.on('closed', () => {
win = null;
});
}

app.on('ready', createWindow);

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});

app.on('activate', () => {
if (win === null) {
createWindow();
}
});

可以看到通过new BrowserWindow()来创建页面,再用其loadURL方法来加载页面。

  • package.json

在scripts里添加"start": "electron ."

修改完成后,npm start。效果如下

主进程与渲染进程

main.js运行的进程是主进程,而创建一个页面时,该页面就会有一个对应的渲染进程。这里先介绍一种我接触到的主进程与渲染进程之间的通信方式:使用ipcMain和ipcRenderer来通信。
继续修改上述例子(…为已存在不需要修改的改吗):

  • index.html
1
2
3
4
5
6
7
8
9
10
11
<body>
...
<button id="showBtn">show other page</button>
<script>
const { ipcRenderer } = require('electron');
var showBtn = document.getElementById('showBtn');
showBtn.addEventListener('click', ()=>{
ipcRenderer.send('show-page');
});
</script>
</body>
  • main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const { app, BrowserWindow, ipcMain } = require('electron');
let win;
let page;

function createWindow() {
...

//创建另一个窗口
page = new BrowserWindow({
width: 300,
height: 300,
show: false
});

page.loadURL(`file://${__dirname}/page.html`) //新窗口

ipcMain.on('show-page', ()=>{
page.show();
});

ipcMain.on('hide-page', ()=>{
page.hide();
});
}
  • 新建page.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>An electron app</title>
</head>
<body>
<h1>Page</h1>
<button id="hideBtn">Hide this page</button>
<script>
const { ipcRenderer } = require('electron');
var hideBtn = document.getElementById('hideBtn');
hideBtn.addEventListener('click', ()=>{
ipcRenderer.send('hide-page');
});
</script>
</body>
</html>

效果如下

所以整体思路是,在main.js这个主进程中通过ipcMain的on来注册方法来监听渲染进程传过来的方法,然后在各个渲染进程中向主进程send所需要调用的方法。感觉有点类似数据交互中的bus总线方法呢。

Electron-vue

我之前学vue的时候就已经装过vue-cli了,所以接下来是

1
2
3
4
vue init simulatedgreg/electron-vue my-project
cd my-project
npm install
npm run dev

效果如下:

更深入的之后再说了。