# Electron桌面应用笔记_结合vue和react
**Repository Path**: fxym888/ElectronNotes
## Basic Information
- **Project Name**: Electron桌面应用笔记_结合vue和react
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-02-03
- **Last Updated**: 2024-12-21
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
#1. 简介
- [官网](https://www.electronjs.org/)
- Electron 是由 GitHub 众多开发者开发的一个开源项目,能够使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序
# 2. 快速上手
## 2.1 安装 electron
初始化 package.json 文件
- npm init
安装 electron
- cnpm i electron –S
## 2.2 配置为入口文件
```js
{
"name": "Electron",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"electron": "electron ." // 这里新增
},
"author": "",
"license": "ISC",
"dependencies": {
"electron": "^17.0.0"
}
}
```
## 2.3 创建 main.js 文件
```js
const { app } = require("electron");
// { app }用来控制程序的生命周期
// 当 Electron 完成初始化时,触发一次
app.on("ready", () => {});
```
## 2.4 创建窗口
```js
const { app, BrowserWindow } = require("electron");
// { app }用来控制程序的生命周期
// { BrowserWindow }用来桌面应用窗口配置
// 当 Electron 完成初始化时,触发一次
app.on("ready", () => {
// 设置启动窗口配置
new BrowserWindow({
width: 800,
height: 800,
});
});
```
### 2.5 如何导入内容
```js
app.on("ready", () => {
// 用const定义myBrowserWindow窗口实例
const myBrowserWindow = new BrowserWindow({
width: 800,
height: 800,
});
// 用创建的myBrowserWindow窗口实例上的loadFile方法引入需要展示的内容文件
myBrowserWindow.loadFile("./src/index.html");
});
```
# 3. 自动刷新页面
- 安装插件
```js
cnpm i -D electron-reloader
```
- 在入口引入插件
```js
const reloader = require("electron-reloader");
reloader(module);
```
# 4. 主进程和渲染进程
Electron 运行 `package.json` 的 `main` 脚本的进程被称为**主进程**。 在主进程中运行的脚本通过创建 web 页面来展示用户界面。 一个 Electron 应用总是有且只有一个主进程。
```js
const { app, BrowserWindow } = require("electron");
// 主进程打印会在cmd里面显示
console.log(module);
```
由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它的叫**渲染进程**的进程中。
在普通的浏览器中,web 页面无法访问操作系统的原生资源。 然而 Electron 的用户在 Node.js 的 API 支持下可以在页面中和操作系统进行一些底层交互。
ctrl+shift+i 打开渲染进程调试
默认打开调试
```js
app.on("ready", () => {
const myBrowserWindow = new BrowserWindow({
width: 800,
height: 800,
});
// 默认打开渲染进程调试工具
myBrowserWindow.webContents.openDevTools();
myBrowserWindow.loadFile("./src/index.html");
});
```
# 5. 自定义原生菜单

## 5.1 自定义菜单
详细文档:https://www.electronjs.org/zh/docs/latest/api/menu
```js
const { app, BrowserWindow, Menu } = require("electron");
app.on("ready", () => {
const myBrowserWindow = new BrowserWindow({
width: 800,
height: 800,
});
myBrowserWindow.loadFile("./src/index.html");
// 定义自定义菜单
const template = [
{
label: "文件",
submenu: [
{
label: "新建窗口",
},
],
},
{
label: "编辑",
submenu: [
{
label: "新建窗口",
},
],
},
];
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
});
```
效果图

## 5.2 给菜单定义点击事件
1、点击打开新窗口
```js
submenu: [
{
label: "新建窗口",
click: () => {
const newMainWindow = new BrowserWindow({
width: 300,
height: 300,
});
newMainWindow.loadFile("./new.html");
},
},
];
```
2、点击打开浏览器
`shell` 模块提供了集成其他桌面客户端的关联功能.
```js
const { BrowserWindow, Menu, shell } = require("electron");
const template = [
{
label: "csdn",
click() {
// 点击打开浏览器
shell.openExternal("https://www.4399.com/");
},
},
];
```
## 5.3 抽离菜单定义
创建 menu.js,将 main.js 里面的菜单部分代码移入 menu.js
```js
// menu.js
const { BrowserWindow, Menu } = require("electron");
// 定义自定义菜单
const template = [
{
label: "文件",
submenu: [
{
label: "新建窗口",
// 自定义菜单点击事件
click: () => {
const newMainWindow = new BrowserWindow({
width: 300,
height: 300,
});
newMainWindow.loadFile("./src/new.html");
},
},
],
},
{
label: "编辑",
submenu: [
{
label: "新建窗口",
},
],
},
];
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
```
```js
// main.js
require("./menu");
```
## 5.4 自定义顶部菜单
- 通过 frame 创建无边框窗口
效果图

```js
const { app, BrowserWindow } = require("electron");
app.on("ready", () => {
new BrowserWindow({
width: 800,
height: 800,
// 创建无边框窗口
frame: false,
});
});
```
- 自定义窗口
```html
```
```css
* {
margin: 0;
padding: 0;
}
.custom-menu {
height: 50px;
width: 100%;
background: pink;
}
.custom-menu ul {
list-style: none;
}
.custom-menu ul li {
float: left;
width: 50px;
line-height: 50px;
text-align: center;
margin-left: 10px;
}
```
重要!!!!!!!!!!!
```css
/* 实现整体菜单拖拽 */
.custom-menu {
-webkit-app-region: drag;
}
/*取消li菜单拖拽 */
.custom-menu li {
-webkit-app-region: no-drag;
}
```
## 5.5 点击创建新窗口
```js
// html
新建窗口;
// js
// remote 通过remote使用主进程的方法
const {
remote: { BrowserWindow },
} = require("electron");
const newWindow = document.querySelector(".new-window");
newWindow.onclick = function () {
new BrowserWindow({
width: 200,
height: 300,
});
};
```
老版本:能够在 html 中使用 node 方法
```js
const mainWindow = new BrowserWindow({
width: 800,
height: 500,
webPreferences: {
// 开启node模块
nodeIntegration: true,
// 开启remote模块
enableRemoteModule: true,
},
});
```
新版本:能够在 html 中使用 node 方法
```js
// 1.首先在项目中通过npm安装它
cnpm i -S @electron/remote
// 2.在主进程中初始化@electron/remote模块,然后才能从渲染器中使用
require('@electron/remote/main').initialize()
require("@electron/remote/main").enable(myBrowserWindow.webContents)
// 3.在主进程中开启remote,也就是webPreferences中添加
webPreferences: {
// 开启渲染进程node模块
nodeIntegration: true,
// 关闭上下文隔离
contextIsolation:false,
// 开启渲染进程remote模块
enableRemoteModule: true,
},
// 4.将代码require('electron').remote替换为require('@electron/remote')
// 在渲染进程中:
// 之前
const { BrowserWindow } = require('electron').remote
// 17+版本
const { BrowserWindow } = require('@electron/remote')
```
## 5.6 点页面打开浏览器
- html
```html
关于我们
```
- js
```js
const { shell } = require("electron");
const goChrome = document.querySelector(".goChrome");
goChrome.onclick = (e) => {
e.preventDefault();
shell.openExternal(e.target.href);
};
```
# 6. 打开对话框读取文件
## 6.1 读取文件
- 定义点击事件
```html
```
- 定义事件函数
打开对话框文档:https://www.electronjs.org/docs/api/dialog
```js
// 打开对话框
function openFile() {
const res = dialog.showOpenDialogSync({
title: "选择文件",
buttonLabel: "哈哈",
filters: [{ name: "Custom File Type", extensions: ["js"] }],
});
const fileContent = fs.readFileSync(res[0]);
dropEl.innerText = fileContent;
}
```
## 6.2 打开文件
- 定义点击事件
```html
```
- 事件函数
```js
const { dialog } = require("@electron/remote");
const fs = require("fs");
// 打开选中文件
const openFile = () => {
const fsRes = dialog.showSaveDialogSync({
// 窗口标题
title: "保存文件",
// 按钮名
buttonLabel: "保存文件",
// 保存类型,数组格式,可以配置多个
filters: [{ name: "index", extensions: ["js"] }],
});
// 获取文件内容
const filesContent = fs.readFileSync(fsRes).toString();
};
```
## 6.3 保存文件
- 定义点击事件
```html
```
- 事件函数
```js
const { dialog } = require("@electron/remote");
const fs = require("fs");
// 保存文件
const saveFile = function () {
const res = dialog.showSaveDialogSync({
title: "保存文件",
buttonLabel: "保存文件",
filters: [{ name: "index", extensions: ["js"] }],
})
// 将输入框的内容保存到文件
fs.writeFileSync(res, textareaEl.value);
}
```
# 7. 定义快捷键
## 7.1 主线程定义
- 引入
```js
const { globalShortcut } = require("electron");
```
- 在 ready 中注册快捷键
```js
globalShortcut.register("CommandOrControl+X", () => {
console.log("ctrl+X is pressed + 打印结果在命令行");
})
```
- 定义快捷键最大、最小、关闭窗口
```js
// 窗口最小
globalShortcut.register("CommandOrControl+T", () => {
myBrowserWindow.unmaximize();
})
// 关闭窗口
globalShortcut.register("CommandOrControl+H", () => {
myBrowserWindow.close();
})
// 窗口最大
globalShortcut.register("CommandOrControl+M", () => {
myBrowserWindow.maximize();
})
```
## 7.2 渲染进程定义
- 通过 remote 注册
```js
const { globalShortcut } = require("@electron/remote");
// 定义快捷键
globalShortcut.register("Ctrl+O", () => {
console.log("ctrl+o")
})
```
# 8. 渲染进程和主线程通讯
- 定义按钮
```html
```
- 渲染进程事件函数
```js
const { ipcRenderer } = require("@electron/remote")
// 点击窗口最大化
const maxWindow = function () {
ipcRenderer.send("max-window")
}
// 点击窗口最小化
const minWindow = function () {
ipcRenderer.send("min-window")
}
// 点击窗口关闭
const closeWindow = function () {
ipcRenderer.send("close-window")
}
```
- 主线程定义事件
```js
// 监听自定义事件
// 最大
ipcMain.on("max-window", (event, arg) => {
myBrowserWindow.maximize()
})
// 最小
ipcMain.on("min-window", (event, arg) => {
myBrowserWindow.unmaximize()
})
// 关闭
ipcMain.on("close-window", (event, arg) => {
myBrowserWindow.close()
})
```
- 渲染进程传参
```js
const minWindow = function () {
ipcRenderer.send("min-window","第二个参数是传递给主线程的参数")
}
```
- 主线程接收参数
```js
ipcMain.on("min-window", (event, arg) => {
// arg是接收的参数
console.log(arg) // 打印结果是:第二个参数是传递给主线程的参数
myBrowserWindow.unmaximize();
});
```
# 09. electron 打包
- 安装 electron-packager
```js
cnpm i electron-packager -D
```
- package.json添加打包任务
```js
// 报错,原因不明。。。。
"build": "electron-packager ./ HelloWorld --platform=win32 --arch=x64 --out ./outApp --overwrite --icon=./favicon.ico"
```
# 10 .electron 结合VUE框架开发
- 利用 vue 脚手架初始化项目
- 在项目中安装 electron
cnpm i electron -S
- 添加 electron 启动配置
```js
"main": "electronMain.js",// 新增的
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"electron": "electron ." // 新增的
},
```
- 配置 main.js
```js
const { app, BrowserWindow } = require("electron")
// 创建窗口
app.on("ready", () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
})
})
```
- 加载 vue 项目
```js
const { app, BrowserWindow } = require("electron")
// 创建窗口
app.on("ready", () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
})
mainWindow.loadURL("http://localhost:8000");
})
```
# 11 .electron 结合REACT框架开发
- 在项目中安装 electron
cnpm i electron -S
- 添加 electron 启动配置..
和vue一样..........不写了.........