介绍
使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序
官方文档
推荐教程:黑马Electron两小时入门
安装
初始化package.json文件
npm init
安装Electron
npm install electron --save-dev
或
cnpm install electron --save-dev
在package.json中添加代码
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron ." //添加这个作为启动命令
},
创建index.js
"main": "index.js",
在package.json
中 main是index.js
,所以要创建一个index.js
作为程序的启动文件(这里也可以使用其它名字,但是一定要对应)
index.js
const { app, BrowserWindow } = require('electron')
app.on('ready', () => {
//创建窗口
const mainWindow = new BrowserWindow({
width: 200,
height: 200
})
//设置可以打开调试
mainWindow.webContents.openDevTools()
//加载要显示的html文件
mainWindow.loadFile('./src/index.html')
})
运行
npm run start
运行结果
热更新
cnpm install --save-dev electron-reloader
在index.js
文件中添加
const reloader=require('electron-reloader')
reloader(module)
基本使用
主进程和渲染进程
Electron 运行 package.json
的 main
脚本的进程被称为主进程。 在主进程中运行的脚本通过创建web页面来展示用户界面。 一个 Electron 应用总是有且只有一个主进程。
由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它的叫渲染进程的进程中。
在普通的浏览器中,web页面无法访问操作系统的原生资源。 然而 Electron 的用户在 Node.js 的 API 支持下可以在页面中和操作系统进行一些底层交互。
ctrl+shift+i打开渲染进程调试
默认打开调试
自定义原生菜单
- menu:创建原生应用菜单和上下文菜单
官方文档
以下都是写在index.js
里
//1、引入Menu
const { app, BrowserWindow,Menu } = require('electron')
//2、定义菜单模板
const menuTemplate = [
{
label: '文件'
},
{
label: '编辑'
}
]
//3、编译菜单模板
const menu = Menu.buildFromTemplate(menuTemplate)
//4、设置菜单
Menu.setApplicationMenu(menu)
- 子菜单
const menuTemplate = [
{
label: '文件',
submenu: [
{
label: '新建文件'
},
{
label: '打开文件'
}
]
},
{
label: '编辑'
}
]
给菜单定义点击事件
const menuTemplate = [
{
label: '文件',
submenu: [
{
label: '新建文件',
click: () => {
const newWindow = new BrowserWindow({
width: 300,
height: 300
})
newWindow.loadFile('./src/news/news.html')
}
}
]
}
]
抽离菜单
单独建立一个menu.js
将关于菜单部分的代码,抽离。然后通过require的方式将代码引入
const { app, BrowserWindow } = require('electron')
//热加载
const reloader = require('electron-reloader')
reloader(module)
//监听初始化完成的事件
app.on('ready', () => {
//创建窗口
const mainWindow = new BrowserWindow({
width: 400,
height: 400
})
//加载菜单
require('./menu.js')
//加载要显示的html文件
mainWindow.loadFile('./src/index.html')
})
自定义顶部菜单
- frame:是否保留边框,默认是保留
注:设置自定义菜单后,原生菜单会失效
const mainWindow = new BrowserWindow({
width: 400,
height: 400,
frame:false //是否保留边框
})
- 编写html,创建顶部菜单
//index.html
<body>
<div>
<ul>
<li>新建</li>
</ul>
</div>
<p>你好世界!</p>
</body>
- 实现自定义菜单的事件
渲染进程中默认是不能使用node,需要在主进程中开启
const mainWindow = new BrowserWindow({
width: 400,
height: 400,
frame: false, //是否保留边框(自定义菜单必须保留)
webPreferences: {
// 开启node模块
nodeIntegration: true,
// 开启remote模块
enableRemoteModule: true,
//禁用上下文隔离
contextIsolation: false
}
})
自定义菜单文件(html)
<body>
<div>
<ul>
<li id="li">新建</li>
</ul>
</div>
<p>你好世界!</p>
<script src="./js/a.js"></script>
</body>
自定义菜单文件(js)
//远程加载(只用于加载渲染进程所需要的模块)
const { remote: { BrowserWindow } } = require('electron')
//获取dom元素
const newWindow = document.getElementById('li')
console.log(newWindow)
newWindow.onclick = function () {
new BrowserWindow({
width: 200,
height: 300
})
}
注:无边框菜单是没法拖拽的,需要拖拽可以参考下面的给文章
点击打开给定文件
shell
模块提供了集成其他桌面客户端的关联功能.
shell模块主进程和渲染进程都可以使用,引入
//主进程
const { app, BrowserWindow, Menu, shell } = require('electron')
//渲染进程
const { remote: { BrowserWindow } , shell} = require('electron')
openExternal
:以桌面的默认方式打开给定的文件。
- 打开网页链接
实例:打开csdn,会调用默认浏览器打开链接
const menuTemplate = [
{
label: 'CSDN',
click: () => {
// 点击打开浏览器
shell.openExternal('https://www.csdn.net/')
}
},
{
label: '编辑'
}
]
- 打开word文件
{
label: '打开word文件',
click: () => {
shell.openExternal('C:/Users/onion/Desktop/a.doc')
}
}
注意:路径分隔符要用/
,不要使用\
打开对话框读取文件
- dialog 对话框(主进程,注意引用方式)
对话框文档
//主进程引入
const { dialog } = require('electron')
//读取文件,并输出(同步方式)
click: () => {
const res = dialog.showOpenDialogSync({
title: 'Electron读取文件', //标题
buttonLabel: '读取', //按钮文字
})
console.log("读取的文件:", res[0])
}
//异步方式
const menuTemplate = [
{
label: '读取文件',
click: () => {
dialog.showOpenDialog({
title: 'Electron读取文件', //标题
buttonLabel: '读取', //按钮文字
}).then(res => {
console.log("读取的文件:", res.filePaths)
}).catch(err => {
console.log(err)
})
}
}
]
注:主进程的输出会在终端里显示,渲染进程的输出在控制台了显示
获取到文件路径后,可以使用fs模块进行文件的读取
const fs = require('fs')
//读取文件
const menuTemplate = [
{
label: '读取文件',
click: () => {
const res = dialog.showOpenDialogSync({
title: 'Electron读取文件', //标题
buttonLabel: '读取', //按钮文字
})
//同步方式
const text = fs.readFileSync(res[0])
console.log(text.toString())
//异步方式
fs.readFile(res[0], (error, data) => {
console.log(data.toString())
})
}
}
]
打开对话框保存文件
//异步
showSaveDialog()
//同步
showSaveDialogSync()
保存文件与读取文件类似
定义快捷键: globalShortcut模块
- 主线程定义
//引入
const { globalShortcut } = require('electron')
//注册
globalShortcut.register('CommandOrControl+X', () => {
console.log("ctrl+x")
})
//注销
globalShortcut.unregister('CommandOrControl+X')
快捷键的注册必须在app.on('ready', () => {}
里面
- 渲染进程定义
略
主进程与渲染进程通信
- 渲染进程
ipcRenderer.send('max-window')
在渲染进程中通过ipcRenderer.send('max-window')
向主进程发生一个事件名
注:ipcRenderer属于渲染进程,不需要通过remote加载
- 主进程
ipcMain.on('max-window', () => {
mainWindow.maximize()
})
主进程中通过ipcMain.on()
注册渲染进程发过来的事件
- 传参
ipcRenderer.send('max-window',参数)
- 接收参数
ipcMain.on('max-window', (event,params) => {
mainWindow.maximize()
})
打包
方式1
- 安装electron-packager
cnpm i electron-packager -D
- 添加打包任务
"build": "electron-packager ./ HelloWorld --platform=win32 --arch=x64 --out ./outApp --overwrite --icon=./favicon.ico"
在package.json里的scripts添加上面的命令
HelloWorld :包名
–platform=win64:window32位
–arch=x64:Linux64位
–out:输出路径
–icon=./favicon.ico":图标
以上包名和图标可以修改,其他不要修改
- 打包命令
npm run build
方式2
- 安装electron-builder
npm install electron-builder --save-dev
- 增加package.json里的设置
"build": {
"mac": {
"target": ["dmg","zip"]
},
"win": {
"target": ["nsis","zip"]
}
},
"scripts": {
"dist": "electron-builder --win --x64"
},
结合vue、react开发
以vue项目为例
1、使用vue脚手架创建项目
2、在项目中安装electron
3、在package.json中配置index.js和启动命令
4、编写index.js
5、加载vue项目,这里加载vue项目启动后在浏览器里的路径
mainWindow.loadURL('http://localhost:3000/')
6、如果要打包vue项目的话,再替换一下地址