一,Electron 快速入门

1、简介

Electron是利用web前端技术进行桌面应用开发的一套框架,它是由Github开发的,利用HTML、CSS、JavaScript来构建跨平台桌面应用程序的一个开源库。Electron通过将Chromium和Node.js合并到同一个运行时环境中,并将其打包成Mac、Windowns、Linux系统下的应用来实现这一目的。

若想开发一个兼容多平台的桌面应用,以往常用的技术框架有GTK、QT等,这些框架受语言限制,且学习成本较高,效率有限。目前一些基于前端技术的hybrid框架很流行,且已经在多个领域得到了广泛的应用和验证,比如利用前端技术+相应的打包工具可开发适配多平台的应用(PC、微信公众号、小程序、Android、IOS等)。Electron就是这样一款框架,为前端技术人员利用web前端技术开发桌面应用带来了可能,开发人员可利用已经掌握的前端技术如Html、CSS、JavaScript,以及结合一些前端技术框架:Vue、Angular、React、webpack,加之浏览器渲染引擎、Electron封装的系统API快速实现一款桌面应用的开发,Electron做了大部分复杂的工作,开发人员只需要专注在核心业务和前端技术本身。同时,通过一定的优化,Electron可以做到很好的体验。

目前有不少知名桌面应用采用Electron开发,如:开发人员熟知的Visual Studio Code、MongoDB桌面版管理工具、Skype桌面版、WhatsApp桌面版、HTTP网络测试工具Postman等。

2、组成

Chromium

Chromium为Electron提供了强大的UI能力,可以不考虑兼容性的情况下,利用强大的Web生态来开发界面。本质上就是chromium(chrome开源版本)浏览器,有最新的东西都会在chromium测试,所以electron可以体验最新的api,这也是好处之一。其多进程架构图如下:

简单描述其原理:

主进程中的RenderProcessHost和 render 进程中的RenderProcess是用来处理进程间通信的(IPC(Inter-Process Communication,进程间通信)。

Render 进程中的 RenderView 内容基于 WebKit(浏览器引擎) 排版展示出来的

Render 进程中的ResourceDispatcher是用来处理资源请求的。Render 进程中如果有请求则创建一个请 求 ID,转发到 IPC,由 Browser 进程中处理后返回。

Chromium 是多进程架构,包括一个主进程,多个渲染进程。

Node.js

Node.js是让Electron有了底层的操作能力,比如文件的读写,甚至是集成C++等等操作,并可以使用大量开源的npm包来完成开发需求

Native API

Native API让Electron有了跨平台和桌面端的原生能力,比如说它有统一的原生界面,窗口、托盘、消息通知这些。

3、涉及前端技术

Electron是基于Chromium和Node.js实现的,所以开发人员所需要使用到的前端技术主要包括以下方面:

(1)、Html、CSS、JavaScript、ES6

(2)、前端开发工具Vue、Angular、React等的一种

(3)、其他网络、缓存、通讯等前端技术

4、架构

Electron 架构和 Chromium 架构类似,也是具有1个主进程和多个渲染进程。但是也有区别:

(1)、在各个进行中暴露了 Native API ,提供了 Native 能力

(2)、引入了 Node.js,所以可以使用 Node 的能力

(3)、但是渲染进程使用node 需要配置,下文会有所提到

        可以简单的理解为Electron为web项目套上了Node.js环境的壳,使得我们可以调用Node.js的丰富的API。这样我们可以用JavaScript来写桌面应用,拓展很多我们在web端不能做的事情。

        Electron的结构示意图如下:electron核心可以分成2个部分即:主进程和渲染进程。

 主进程

Electron 运行 package.json 的 main 脚本的进程被称为主进程 (只有一个)。

主进程特点:
                主进程连接着操作系统和渲染进程,可以把她看做页面和计算机沟通的桥梁
                进程间通信、窗口管理
                全局通用服务
                一些只能或适合在主进程做的事情,如浏览器下载、全局快捷键处理、托盘、session
                维护一些必要的全局状态

渲染进程
        渲染进程就是我们所熟悉前端环境了。只是载体改变了,从浏览器变成了window。

注:出于安全考虑,渲染进程是不能直接访问本地资源的),因此都需要在主进程完成。

渲染进程特点:
                Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 多进程架构也被使用到。
                每个web页面运行在自己的进程中。每个渲染进程是相互独立的且只关心自己网页。
                使用BrowserWindow类开启一个渲染进程并将这个实例运行在该进程中,当一个被销毁后,相应的渲染进程也会被终止。
                渲染进程不能调用原生资源,但同样包含Node.js环境,所以可以引入Node.js。

主进程与渲染进程的区别
        主进程使用 BrowserWindow 实例创建网页。
        每个 BrowserWindow 实例都在自己的渲染进程里运行着一个网页。当一个 BrowserWindow 实例被销毁后,相应的渲染进程也会被终止。
        主进程管理所有页面和与之对应的渲染进程。
        由于在网页里管理原生 GUI 资源是非常危险而且容易造成资源泄露,所以在网页面调用 GUI 相关的 APIs 是不被允许的。如果你想在网页里使用 GUI 操作,其对应的渲染进程必须与主进程进行通讯,请求主进程进行相关的 GUI 操作。

二,Electron 桌面环境搭建

1、安装Node.js

(1)、默认安装,一直next

(2)、验证node是否安装成功

打开cmd窗口,在命令窗口输入命令:node -v ,如果出现版本号,即表示安装成功

还可以查看npm的版本,在cmd命令窗口中输入命令:npm -v

2、安装Electron

(1)、安装cnpm,采用淘宝镜像安装electron

打开cmd窗口,在命令窗口输入命令下载安装:

npm install cnpm -g  --registry=https://registry.npm.taobao.org

在cmd命令窗口中输入命令:cnpm -v 查看版本信息

(2)、安装electron,全局安装

打开cmd窗口,在命令窗口输入命令下载安装:cnpm install electron -g

在cmd命令窗口中输入命令:electron -v 查看版本信息

3、测试项目

(1)、使用WebStorm新建空项目

(2)、在根目录下新建一个html文件,文件名称为helloworld.html

(3)、在根目录下新建一个 main.js 文件,并填写如下代码,这个就是 Electron 的主进程文件

// 1、引入electron模块
let electron = require('electron');// 2、创建electron引用
let app = electron.app;// 3、创建窗口引用
let BrowserWindow = electron.BrowserWindow;// 4、声明要打开的主窗口
let mainWindow = null;app.on('ready',() => {// 设置窗口大小mainWindow = new BrowserWindow({width:300, height:200});// 加载哪个页面mainWindow.loadFile('helloworld.html');// 监听关闭事件,把主窗口设置为null,否则内存占用越来越多mainWindow.on('closed',() => {mainWindow = null;})
})

(4)、在终端位置直接使用命令:npm init --yes 来初始化 package.json 文件

文件生成后如下:

{"name": "electron","version": "1.0.0","description": "","main": "main.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC"
}

(5)、运行项目,在终端位置输入命令:electron . (注意命令最后带 .)

三,Electron 项目实战

1、Electron remote模块的使用

Electron 的 API 方法和模块也是分为可以在主进程和渲染进程中使用。那如果我们想在渲染进程中使用主进程中的模块方法时,可以使用 Electro remote 来解决在渲染和主进程间的通讯。这节我们就实现一个通过Web中的按钮打开新窗口。

(1)、在项目根目录下,新建一个 demo1.html 文件,然后快速生成html的基本结构,编写一个按钮,引入渲染的js页面。代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>demo1</title>
</head>
<body><button id="btn">打开新的窗口</button><script src="render/demo1.js"></script>
</body>
</html>

(2)、在render文件夹下,新建一个 demo3.js 文件,然后编写如下代码:

// 1、获取ID为btn的选择器
const btn = this.document.querySelector('#btn');// 2、创建窗口引用
const BrowserWindow = require('electron').remote.BrowserWindow;// 3、打开窗口
window.onload = function (){btn.onclick = () => {newWin = new BrowserWindow({width: 300, height: 200})newWin.loadFile('test1.html')newWin.on('close', () => {newWin = null})}
}

(3)、在项目根目录下创建test1页面,然后写入下面的代码:


<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>test1</title>
</head>
<body><h1>hello World!</h1>
</body>
</html>

(4)、 修改 main.js ,增加全量使用node.js,内容:

// 1、引入electron模块
let electron = require('electron');// 2、创建electron引用
let app = electron.app;// 3、创建窗口引用
let BrowserWindow = electron.BrowserWindow;// 4、声明要打开的主窗口
let mainWindow = null;app.on('ready',() => {// 设置窗口大小mainWindow = new BrowserWindow({width:300,height:200,// 增加全量使用node.js,因为我们要使用node里的fs模块// enableRemoteModule 设置为true,否则不允许在渲染器上使用 remotewebPreferences: { nodeIntegration: true, enableRemoteModule: true}});// 加载哪个页面mainWindow.loadFile('demo1.html');// 监听关闭事件,把主窗口设置为null,否则内存占用越来越多mainWindow.on('closed',() => {mainWindow = null;})
})

(5)、在终端中运行 electron . 命令,查看测试效果

2、Electron创建菜单和基本使用

(1)、在项目的根目录下新建一个main文件夹,用于存放主进程中用到的代码,在文件夹中新建文件menu.js,内容如下:

const { Menu, BrowserWindow } = require('electron')// 菜单模板
let template = [{label: '前端技能',submenu: [{label: 'JavaScript',// 加入click事件click: () => {win = new BrowserWindow({width: 200,height: 200,webPreferences: { nodeIntegration: true }})win.loadFile('test2.html')win.on('closed', () => {win = null})}},{ label: 'TypeScript' }]},{label: '后端技能',submenu: [{ label: 'golang' },{ label: 'Python' }]}
]// 设置菜单
let m = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(m)

(2)、项目根目录新建测试文件 test2.html,内容如下:

<!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>hello World!</h1>
</body>
</html>

(3)、项目根目录新建测试文件 demo2.html,内容如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Demo2</title>
</head>
<body></body>
</html>

(4)、修改 main.js ,并在ready生命周期中,引入自定义菜单文件 require('./main/menu.js');

// 1、引入electron模块
let electron = require('electron');// 2、创建electron引用
let app = electron.app;// 3、创建窗口引用
let BrowserWindow = electron.BrowserWindow;// 4、声明要打开的主窗口
let mainWindow = null;app.on('ready',() => {// 自定义菜单require('./main/menu.js');// 设置窗口大小mainWindow = new BrowserWindow({width:300,height:200,// 增加全量使用node.js,因为我们要使用node里的fs模块// enableRemoteModule 设置为true,否则不允许在渲染器上使用 remotewebPreferences: { nodeIntegration: true, enableRemoteModule: true}});// 加载哪个页面mainWindow.loadFile('demo2.html');// 监听关闭事件,把主窗口设置为null,否则内存占用越来越多mainWindow.on('closed',() => {mainWindow = null;})
})

(5)、在终端中运行 electron . 命令,查看测试效果

3、Electron制作右键菜单

(1)、菜单快捷键绑定

        接着上面的 demo2 ,绑定快捷键的属性是 accelerator 属性,比如我们要用快捷键新打开一个窗口,我们的 menu.js 代码可以写成这样:accelerator:`ctrl+n`

const { Menu, BrowserWindow } = require('electron')// 菜单模板
let template = [{label: '前端技能',submenu: [{label: 'JavaScript',// 绑定快捷键accelerator:`ctrl+n`,// 加入click事件click: () => {win = new BrowserWindow({width: 200,height: 200,webPreferences: { nodeIntegration: true }})win.loadFile('test2.html')win.on('closed', () => {win = null})}},{ label: 'TypeScript' }]},{label: '后端技能',submenu: [{ label: 'golang' },{ label: 'Python' }]}
]// 设置菜单
let m = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(m)

(2)、创建右键菜单

右键菜单的响应事件是写在渲染进程中的,也就是写在根目录下的demo2.html中的,所以要使用,就要用到remote模块进行操作了,先来看看右键的相应事件,我们打开 render 文件夹,然后打开 demo2.js 文件,编写一个右键菜单的监听事件,代码如下:

window.addEventListener('contextmenu',function () {alert('您好!');
})

修改demo2.html,增加引入 <script src="render/demo2.js"></script>

当我们要使用 Menu 模块,它是主线中的模块,如果想在渲染线程中使用,就必须使用 remote 。demo2.js 代码如下:

// window.addEventListener('contextmenu',function () {
//     alert('您好!');
// })const { remote } = require('electron')let rigthTemplate = [{label: '粘贴',accelerator: 'ctrl+v'},{label: '复制',accelerator: 'ctrl+c'}
]let m = remote.Menu.buildFromTemplate(rigthTemplate);window.addEventListener('contextmenu',function (e) {// 阻止当前窗口默认事件e.preventDefault();// 把菜单模板添加到右键菜单m.popup({window:remote.getCurrentWindow()});
})

(3)、程序打开调试模式,运行测试

由于我们已经定义了顶部菜单,没有了打开调试模式的菜单了,这时候可以使用程序来进行打开。

在 main.js 主进程的 ready 生命周期中加入如下这句代码就可以了:

mainWindow.webContents.openDevTools()

4、Electron中通过链接打开浏览器

5、Electron中嵌入网页和打开子窗口

6、Electron Window.open子窗口和父窗口间的通信

7、Electron选择文件对话框

8、Electron保存对话框的操作

9、Electron消息对话框的操作

10、Electron断网提醒功能制作

11、Electron底部通知消息的制作

12、Electron注册全局快捷键

13、Electron剪贴板事件的使用

14、Electron-vue开发项目

四,Electron 项目进阶

1、克隆示例项目

(1)、项目仓库地址

git clone https://github.com/electron/electron-quick-start

(2)、下载完成后进入 electron-quick-start 目录中

(3)、使用淘宝镜像下载项目所需的依赖

采用如下命令设置淘宝镜像

npm  config set ELECTRON_MIRROR https://npm.taobao.org/mirrors/electron/

采用命令 npm install 进行所需依赖安装

(4)、启动工程测试

采用命令 npm start 启动项目


2、app常用事件

(1)、ready 当electron完成初始化时被触发

app.on('ready',() => {console.log("*******ready******");createWindow();
})

(2)、window-all-closed 所有窗口被关闭

app.on('window-all-closed', function () {console.log("*******window-all-closed******");
})

(3)、quit 在所有应用程序退出时发出

app.on('window-all-closed', function () {if (process.platform !== 'darwin') {console.log("*******quit******");app.quit()}
})

(4)、open-file 在应用中要打开一个文件时发出

(5)、open-url 应用中要打开一个URL网址时发出

(6)、activate 当应用被激活时发出

3、webContents常用事件

(1)、did-finish-load 导航完成时触发,即选项卡的旋转器将停止旋转,并指派 onload 事件后

mainWindow.webContents.on('did-finish-load',()=>{console.log("did-finish-load")
})

(2)、dom-ready 一个框架中的文本加载完成后触发该事件

mainWindow.webContents.on('dom-ready',()=>{console.log("dom-ready")
})

4、process 进程对象

(1)、编辑Index.html文件,如下:

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"><link href="./styles.css" rel="stylesheet"><title>Process</title></head><body><button id="buttonProcess" >查看Process信息</button><script src="./renderer.js"></script></body>
</html>

(2)、编辑渲染进程renderer.js,定义查看进程信息

var processBtn=document.getElementById('buttonProcess');processBtn.onclick=getProcessInfo;function getProcessInfo() {console.log("getCPUUsage=",process.getCPUUsage());console.log("arch=",process.arch);console.log("platform=",process.platform);console.log("env=",process.env);
}

5、File对象

在文件系统中,使用HTML5 File 原生API操作文件

DOM文件接口为原生文件提供了抽象,以便让用户使用HTML5文件API直接处理原生文件对象。Electron已经向文件对象接口添加了一个path属性,在文件系统中暴露出文件的真实路径

(1)、在index.html文件中添加文件拖动代码

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"><link href="./styles.css" rel="stylesheet"><title>Process</title></head><body><div class="for_file_drag" id="drag_test"><h2>File对象</h2><span>往这里拖动文件</span></div><button id="buttonProcess" >查看Process信息</button><script src="./renderer.js"></script></body>
</html>

(2)、在styles.css样式中新增拖拽区域的样式

.for_file_drag {width: 100%;height: 200px;background: pink;
}

(4)、在renderer.js中添加如下方法

const electron = require("electron");
const fs = require('fs');const dragWrapper = document.getElementById("drag_test");dragWrapper.addEventListener('drop',(e) => {e.preventDefault();const files = e.dataTransfer.files;if(files && files.length>0){// 获取文件路径const path = files[0].path;console.log('path',path);// 获取文件内容const content = fs.readFileSync(path);console.log(content.toString());}
})dragWrapper.addEventListener('dragover',(e)=>{e.preventDefault();
})

(5)、测试

6、webview

在一个独立的frame和进程里面显示外部web内容

7、window.opn

8、BrowserWindowProxy

9、BrowserWindow

10、BrowserView

11、dialog

12、系统快捷键

13、主进程与渲染进程通信

14、原生应用菜单

15、网络

16、集成VUE

16、E

Electron从入门到精通相关推荐

  1. FFmpeg从入门到精通-云享读书会

    前言 FFmpeg是一款开源软件,用于生成处理多媒体数据的各类库和程序.FFmpeg可以转码.处理视频和图片(调整视频.图片大小,去噪等).打包.传输及播放视频.作为最受欢迎的视频和图像处理软件,它被 ...

  2. Web前端从入门到精通(第一周)

    Web前端从入门到精通(第一周) HTML+CSS系列之导学 1.拨云见日:HTML.CSS.切图流程.PC企业布局.PC游戏站布局 2.溯本求源:扩展HTML.扩展CSS.HTML5新语法.CSS3 ...

  3. java从入门到精通_想要开始学java?你要的java从入门到精通布列如下!

    java从入门到精通,让我来告诉你! 毫无疑问,java是当下最火的编程语言之一.对于许多未曾涉足计算机编程的领域「小白」来说,深入地掌握java看似是一件十分困难的事.其实,只要掌握了科学的学习方法 ...

  4. 虚幻引擎5(UE5)实时VFX游戏特效制作入门到精通

    UE5 Niagara学习教程  课程获取:虚幻引擎5(UE5)实时VFX游戏特效制作入门到精通-云桥网 你会学到什么 我将通过创建各种各样的实时效果来教你虚幻引擎中强大的粒子系统. 我们将从简单的基 ...

  5. Revit:从入门到精通学习教程

    流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确) |大小:8.07 GB |时长:12h 16m Re ...

  6. 《Java 开发从入门到精通》—— 2.2 编写第一段Java程序

    本节书摘来异步社区<Java 开发从入门到精通>一书中的第2章,第2.2节,作者: 扶松柏 , 陈小玉,更多章节内容可以访问云栖社区"异步社区"公众号查看. 2.2 编 ...

  7. meteor从入门到精通_我已经大规模运行Meteor一年了。 这就是我所学到的。

    meteor从入门到精通 by Elie Steinbock 埃莉·斯坦博克(Elie Steinbock) 我已经大规模运行Meteor一年了. 这就是我所学到的. (I've been runni ...

  8. Java学习从入门到精通的学习建议

    想要学好java技术,首先打好基础很重要,不论学什么基础都是重中之重,学习Java更是如此.如:基础语法.核心类库.面向对象编程.异常.集合.IO流等基础如果学不好,那么后边更深入的语法也不容易学会. ...

  9. ASP网络编程从入门到精通 下载

    <ASP网络编程从入门到精通> 清华大学出版社 特点: 面向ASP零基础读者,循序渐进 全面分析ASP技术细节 用代码描述个个知识点,操作性强 通过典型模块设计,体会ASP的奥妙 通过网上 ...

最新文章

  1. 是时候重新定义安全了,阿里云肖力解读安全责任共担模型
  2. mysql忽略大小写配置cnetos_CentOS7下安装MYSQL8.X并设置忽略大小写
  3. python 对输入的数据进行排序_使用插入排序对输入数据排序
  4. Zookeeper运维问题集锦
  5. 【牛客161 - A】字符串(尺取法,桶标记法)
  6. django项目基础
  7. Linux系统启动流程图
  8. 阿里云搭建CDH集群配置邮箱告警
  9. C语言实现-航空订票系统(飞机订票系统)单机版联网版
  10. 京瓷2211打印机清零_打印机墨粉盒清零的方法
  11. 递归,与,科赫雪花曲线
  12. linux ubuntu因为没有正常关机,导致开机出现gun grub
  13. Android persistent机制
  14. ios13一直在估算剩余时间怎么办
  15. Python之You-Get库学习
  16. Python私有属性与私有方法
  17. zabbix 监控下载安装
  18. Error: Corrupted zip: missing XXX bytes.
  19. 数据存储之Archiver、Unarchiver、偏好设置
  20. 菜谱:木瓜花生鸡脚汤和苦瓜黄豆排骨煲

热门文章

  1. 小曾曾读书笔记 ||《大数据实践之路》
  2. js逆向知识-Ja3指纹学习
  3. 【Fortran】过程设计之三(函数FUNCTION)
  4. volatile c 关键字
  5. 你真的了解一句话木马吗?
  6. 联想S820 MIUI刷机包 MIUI 4.4.30 流畅运行 在线主题破解
  7. Python日志解析入库优化
  8. 一文搞定Netty,打造单机百万连接测试!
  9. 从老宋的角度看,自然语言处理领域如何学习?
  10. python的网络编程用途_python---网络编程