携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天, 点击查看活动详情
1.第一个electron应用
首先打开vsCode终端输入mkdir electron-demo创建文件夹,
cd到electron-demo文件夹,创建一个package.json文件,里面输入如下代码:
{
"name": "electron-demo", // 项目名
"version": "1.0.0", // 版本号
"main": "./src/index.js", // 入口文件
}
项目结构
安装electron,npm i electron,在index.js里面输入如下代码:
const { app, BrowserWindow } = require('electron')
app.on('ready', () => {
// 创建BrowserWindow实例
let mainWindow = new BrowserWindow({
// 设置窗口大小,最小minWidth minHeight 最大maxWidth maxHeight
width: 800,
height: 600,
// x,y控制窗口打开的位置
x: 100,
y: 100,
})
// 加载本地index.html文件
mainWindow.loadFile('./src/views/index.html')
mainWindow.on('close', () => { // 页面关闭的时候清除该变量,防止内存泄漏
mainWindow = null
})
})
index.html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>我是第一个electron应用</h1>
</body>
</html>
在终端输入npm init,操作如下
package.json第一个应用完整代码如下
{
"name": "electron-demo",
"version": "1.0.0",
"main": "./src/index.js",
"dependencies": {
"electron": "^19.0.9"
},
"devDependencies": {},
"scripts": {
"test": "electron ." // 启动程序
},
"author": "",
"license": "ISC",
"description": ""
}
终端输入npm run test或者electron .即可启动第一个electron,运行成功图片如下
2.访问Node.js环境
项目结构如下:
index.html代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>我是第一个electron应用</h1>
<button id="btn">新建窗口</button>
<script src="../child.js"></script>
</body>
</html>
index.js代码如下
const { app, BrowserWindow } = require('electron')
app.on('ready', () => {
// 加载本地index.html文件
let mainWindow = new BrowserWindow({
// 设置窗口大小,minWidth maxWidth minHeight maxHeight
width: 800,
height: 600,
// x,y控制窗口打开的位置
x: 100,
y: 100,
})
mainWindow.webContents.openDevTools() // 打开控制台
// 加载本地index.html文件
mainWindow.loadFile('./src/views/index.html')
mainWindow.on('close', () => {
mainWindow = null
})
// 默认最大化
// let mainWidth = new BrowserWindow({
// show: false
// })
// mainWidth.maximize()
// mainWidth.show()
// 默认全屏
// let mainWidth = new BrowserWindow({ fullscreen: true})
})
child.html代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
background-color: pink;
}
</style>
</head>
<body>
<h1>我是新建的窗口</h1>
</body>
</html>
child.js代码如下
const btn = document.getElementById('btn')
console.log(123);
const BrowserWindow = require('electron').remote.BrowserWindow
btn.onclick = function() {
let win = new BrowserWindow({
width: 300,
height: 200
})
win.loadFile('./src/views/child.html')
win.on('close', () => {
win = null
})
}
这里我们会发现报ReferenceError: require is not defined,
我们需要在index.js文件中new BrowserWindow里面加入webPreferences: { nodeIntegration: true },但是添加之后还是报require is not defined,这是因为在electron12版本中默认contextIsolation: true, 我们只需要在原基础上在添加如下代码
contextIsolation: false
新index.js代码如下
const { app, BrowserWindow } = require('electron')
app.on('ready', () => {
// 加载本地index.html文件
let mainWindow = new BrowserWindow({
// 设置窗口大小,minWidth maxWidth minHeight maxHeight
width: 800,
height: 600,
// x,y控制窗口打开的位置
x: 100,
y: 100,
webPreferences: {
nodeIntegration: true, // 允许在这个渲染进程调用node.js
contextIsolation: false, // 解决require is not defined
}
})
mainWindow.webContents.openDevTools() // 打开控制台
// 加载本地index.html文件
mainWindow.loadFile('./src/views/index.html')
mainWindow.on('close', () => {
mainWindow = null
})
})
但是我们会发现确实不报require is not defined了,但是开始报Cannot read properties of undefined (reading 'BrowserWindow'),
这是因为remote在electron14的时候废弃了remote模块,所以需要我们自己安装@electron/remote包。如果你想要了解@electron/remote可以点击这里。
npm install @electron/remote
这里我们在index.js中添加如下代码
webPreferences: {
nodeIntegration: true, // 允许在这个渲染进程调用node.js
contextIsolation: false, // 解决require is not defined
enableRemoteModule:true // 开启remote
}
在主进程中进行初始化
require('@electron/remote/main').initialize()
require('@electron/remote/main').enable(mainWindow.webContents)
2.在child.js添加如下代码,
将const BrowserWindow = require('electron').remote.BrowserWindow
修改为const BrowserWindow = require('@electron/remote').BrowserWindow,在new BrowserWindow中添加
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
,修改完后就可以点击新建窗口创建成功窗口啦(^-^)。 运行成功图片如下
3.自定义菜单
项目结构
在index.js文件中添加require('./menu.js'),index.js代码如下
const { app, BrowserWindow } = require('electron')
// 导入自定义菜单menu.js
require('./menu.js')
app.on('ready', () => {
// 加载本地index.html文件
let mainWindow = new BrowserWindow({
// 设置窗口大小,minWidth maxWidth minHeight maxHeight
width: 800,
height: 600,
// x,y控制窗口打开的位置
x: 100,
y: 100,
webPreferences: {
nodeIntegration: true, // 允许在这个渲染进程调用node.js
contextIsolation: false, // 解决require is not defined
enableRemoteModule:true // 开启remote
}
})
// 解决报Cannot read properties of undefined (reading 'BrowserWindow'
require('@electron/remote/main').initialize()
require('@electron/remote/main').enable(mainWindow.webContents)
mainWindow.webContents.openDevTools() // 打开控制台
// 加载本地index.html文件
mainWindow.loadFile('./src/views/index.html')
mainWindow.on('close', () => {
mainWindow = null
})
// 默认最大化
// let mainWidth = new BrowserWindow({
// show: false
// })
// mainWidth.maximize()
// mainWidth.show()
// 默认全屏
// let mainWidth = new BrowserWindow({ fullscreen: true})
})
lately.html代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我是新建窗口</title>
</head>
<body>
<h1>我是新建窗口</h1>
</body>
</html>
menu.js代码如下
const { Menu, BrowserWindow } = require('electron')
// 创建菜单模板,数组里的每一个对象都是一个菜单
const template = [
{
label: '文件',
// submenu 代表下一级菜单
submenu: [
{
label: '新建窗口',
accelerator: 'ctrl+n', // 快捷键
click: () => {
let win = new BrowserWindow({ // 添加点击事件
width: 400,
height: 400
})
win.loadFile('./src/views/lately.html')
win.on('close', () => { // 监听是否关闭窗口
win = null
})
}
},
{ label: '打开最近文件' },
{
label: '新建文件',
click: () => {
let win = new BrowserWindow({
width: 300,
height: 150
})
win.on('close', () => {
win = null
})
}
}
]
},
{
label: '编辑',
submenu: [
{ label: "撤销", accelerator: "ctrl+z" },
{
label: "查找",
accelerator: "ctrl+f",
submenu: [
{ label: "在文件中查找", accelerator: "ctrl+shift+f" }
]
},
{ label: "恢复" }
]
},
{
label: "选择",
submenu: [
{
label: "全选",
accelerator: "ctrl+a"
}
]
}
]
// 从模板中创建菜单
const menu = Menu.buildFromTemplate(template)
// 设置为应用程序菜单
Menu.setApplicationMenu(menu)
运行结果如图
4.electron应用设置无边框
- 在创建窗口的时候设置无边框,这里我们可以看到菜单也消失了。在index.js中输入如下代码
new BrowserWindow({
frame: false, // 让桌面应用无边框,菜单栏也消失了
})
其实菜单栏还在,我们可以通过快捷键调出菜单,也可以直接删除菜单mainWidth.removeMenu()。完整index.js代码如下
const { app, BrowserWindow } = require('electron')
// 导入自定义菜单menu.js
require('./menu.js')
app.on('ready', () => {
// 加载本地index.html文件
let mainWindow = new BrowserWindow({
// frame: false, // 让桌面应用无边框,菜单栏也消失了
// 设置窗口大小,minWidth maxWidth minHeight maxHeight
width: 800,
height: 600,
// x,y控制窗口打开的位置
x: 100,
y: 100,
webPreferences: {
nodeIntegration: true, // 允许在这个渲染进程调用node.js
contextIsolation: false, // 解决require is not defined
enableRemoteModule:true // 开启remote
}
})
// 解决报Cannot read properties of undefined (reading 'BrowserWindow'
require('@electron/remote/main').initialize()
require('@electron/remote/main').enable(mainWindow.webContents)
mainWindow.removeMenu() // 删除菜单
mainWindow.webContents.openDevTools() // 打开控制台
// 加载本地index.html文件
mainWindow.loadFile('./src/views/index.html')
mainWindow.on('close', () => {
mainWindow = null
})
// 默认最大化
// let mainWidth = new BrowserWindow({
// show: false
// })
// mainWidth.maximize()
// mainWidth.show()
// 默认全屏
// let mainWidth = new BrowserWindow({ fullscreen: true})
})
- 我们会发现没有边框的时候,我们不能拖动窗口,在css中我们可以设置哪个可以进行拖拽/禁止拖拽。
- 例如
body{ -webkit-app-region: drag | no-drag; }
- 例如
5.系统托盘
- 我们在使用电脑的时候,可以看到一些,我们不想在电脑栏看见的应用,又不想关闭,就可以把它设置到系统托盘中
如果你想要了解更多,可以点击这里。
- 当然,我们可以在主进程index.js中添加系统托盘,添加左键事件,右键事件带菜单等。
注意作为系统托盘图标的图片不能是改了后缀名的。例如:bg.png的图片我们改了后缀名改成了bg.jpg,然后我们使用bg.jpg的话,托盘图标是不会显示的哟,只有bg.png原来的这种才会显示。
const { app, BrowserWindow, Tray, nativeImage, Menu } = require('electron')
const path = require('path')
// 导入自定义菜单menu.js
require('./menu.js')
let mainWindow
app.on('ready', () => {
// 加载本地index.html文件
mainWindow = new BrowserWindow({
// frame: false, // 让桌面应用无边框,菜单栏也消失了
// 设置窗口大小,minWidth maxWidth minHeight maxHeight
width: 800,
height: 600,
// x,y控制窗口打开的位置
x: 100,
y: 100,
webPreferences: {
nodeIntegration: true, // 允许在这个渲染进程调用node.js
contextIsolation: false, // 解决require is not defined
enableRemoteModule:true // 开启remote
}
})
// 创建icon图标
const icon = nativeImage.createFromPath(
path.join(__dirname,'/images/bg.png')
)
// 实例化一个托盘对象,传入的是托盘的图标
let tray = new Tray(icon)
// 移动到托盘上的提示
tray.setToolTip('electron demo is running')
// 设置title
tray.setTitle('electron demo')
// 监听托盘右键事件
tray.on('right-click', () => {
// 右键菜单模块
const template = [
{
label: '设置'
},
{
label: '退出',
click: () => app.quit()
}
]
// 通过Menu创建菜单
const menu = Menu.buildFromTemplate(template)
// 让我们写的托盘右键的菜单代替原来的
tray.popUpContextMenu(menu)
})
//监听点击托盘的事件
tray.on('click', () => {
// 这里来控制窗口的显示和隐藏
if (mainWindow.isVisible()) {
mainWindow.hide()
} else {
mainWindow.show()
}
})
// 解决报Cannot read properties of undefined (reading 'BrowserWindow'
require('@electron/remote/main').initialize()
require('@electron/remote/main').enable(mainWindow.webContents)
// mainWindow.removeMenu() // 删除菜单
mainWindow.webContents.openDevTools() // 打开控制台
// 加载本地index.html文件
mainWindow.loadFile('./src/views/index.html')
mainWindow.on('close', () => {
mainWindow = null
app.quit()
})
// 默认最大化
// let mainWidth = new BrowserWindow({
// show: false
// })
// mainWidth.maximize()
// mainWidth.show()
// 默认全屏
// let mainWidth = new BrowserWindow({ fullscreen: true})
})
app.on('window-all-closed', () => {
mainWindow = null
})
6.electron 控制台打印乱码问题?
我们可能在Windows的控制台会出现中文乱码的问题,当我们在Windows的控制台下输入chcp,可以查看到当前字符编码,常见的gb2312的值是936,utf8的值是65001。这种情况下只要对package.json进行设置就能解决。
"test": "chcp 65001 && electron ."
7.如何对项目进行打包?
打包也是必不可少的一步,这里介绍两种比较成熟的打包工具:electron-packager和electron-builder。这两个工具主要是对其进行配置。
electron-packager
先进行安装
npm install electron-packager --save-dev
安装好之后要配置electron-packager的基本命令,下面为官方文档中的基本格式:
electron-packager <sourcedir> <appname> --platform=<platform> --arch=<arch> [optional flags...]
简要的介绍一下各个参数所代表的意思:
- sourcedir:项目所在路径
- appname:应用名称(打包后文件的名称)
- platform:确定了你要构建哪个平台的应用(Windows、Mac 还是 Linux)
platform=win32代表Windowsplatform=darwin代表Macplatform=linux代表Linux
- arch:决定了使用 x86 还是 x64 还是两个架构都用
- optional options:可选选项
- --out表示打包后生成的文件的目录
- --app-version表示打包生成文件的版本号
- --overwrite表示删除原有的打包文件,生成新的打包文件
- --icon表示打包文件的图标
下面为一个例子,供参考
"scripts": {
"test": "electron .",
"build32": "electron-packager ./ 黑洞 --platform=win32 --arch=ia32 --out=./dist --app-version=1.0.0 --overwrite --icon=hd.ico",
"build": "electron-packager . 黑洞 --platform=win32 --arch=x64 --out=./dist --asar --app-version=1.0.0 --overwrite --icon=hd.ico"
},
build32打包的为32位,build打包的为64位,打包的文件在dist文件夹下面,如下图
注意哟这里和前面系统托盘图标一样,我们不能使用只是改了后缀名的ico图标哟,如果没有合适的ico图片,可以点击这里。
最后
感谢大家能看到这里,若有问题请指正(^-^)。