# electron
**Repository Path**: lonsun/electron
## Basic Information
- **Project Name**: electron
- **Description**: 公开课-electron源码
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 3
- **Created**: 2020-11-03
- **Last Updated**: 2024-12-07
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
#### 简介
+ [官网](https://www.electronjs.org/)
+ Electron是由GitHub开发,使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序
+ Electron 可以让你使用纯 [JavaScript](https://www.w3cschool.cn/javascript/) 调用丰富的原生 APIs 来创造桌面应用。你可以把它看作是专注于桌面应用
+ 在PC端混合app开发中,nwjs和electron都是可选的方案,它们都是基于Chromium和Node的结合体, 而electron相对而言是更好的选择方案,它的社区相对比较活跃,bug比较少,文档先对利索简洁。
+ electron 相对来说比 [nw.js](https://www.codebye.com/tag/nw-js) 靠谱。有一堆成功的案例:Atom 编辑器 2. Slack (那个独角兽公司)3. Visual Studio Code 4. WordPress 等等。。
+ Node. js 的所有 [内置模块 ](https://nodejs.org/api/)都在Electron中可用, 第三方 node 模块中也完全支持 (包括 [原生模块 ](https://www.electronjs.org/docs/tutorial/using-native-node-modules))。
+ Electron 还为开发原生桌面应用程序提供了一些额外的内置模块。 某些模块仅在主进程中可用, 有些仅在渲染进程 (web 页) 中可用, 而有些在这两个进程中都可以使用。
#### 安装electron
+ npm init
+ cnpm I electron –S
+ npx electron
#### 5分钟快速上手
+ 创建main.js文件
```js
const electron = require('electron')
const app = electron.app
app.on('ready', ()=>{
new electron.BrowserWindow({
width: 800,
height: 300
})
})
```
+ 将main.js文件配置为入口文件,通过npm run start启动
```js
{
"name": "electron-demo",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron ."
},
"author": "",
"license": "ISC",
"dependencies": {
"electron": "^8.3.0"
}
}
```
+ 通过BrowserWindow的实例来配置加载的页面文件
```js
app.on('ready', ()=>{
const mainWindow = new BrowserWindow({
width: 800,
height: 500
})
mainWindow.loadFile('./index.html')
})
```
#### 主进程和渲染进程
Electron 运行 `package.json` 的 `main` 脚本的进程被称为**主进程**。 在主进程中运行的脚本通过创建web页面来展示用户界面。 一个 Electron 应用总是有且只有一个主进程。
由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它的叫**渲染进程**的进程中。
在普通的浏览器中,web页面通常在沙盒环境中运行,并且无法访问操作系统的原生资源。 然而 Electron 的用户在 Node.js 的 API 支持下可以在页面中和操作系统进行一些底层交互。
ctrl+shift+i打开渲染进程调试
```js
app.on('ready', ()=>{
const mainWindow = new BrowserWindow({
width: 800,
height: 500
})
mainWindow.loadFile('./index.html')
const mainWindow2 = new BrowserWindow({
width: 800,
height: 500
})
mainWindow2.loadFile('./index2.html')
})
```
#### 自定义原生菜单
##### 自定义菜单
```js
const template = [
{
label: '文件',
submenu: [
{
label: '新建窗口'
}
]
},
{
label: '编辑',
submenu: [
{
label: '新建窗口'
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
```
##### 给菜单定义点击事件
```js
submenu: [
{
label: '新建窗口',
click: ()=>{
const newMainWindow = new BrowserWindow({
width: 300,
height: 300
})
newMainWindow.loadFile('./new.html')
}
}
]
```
##### 抽离菜单定义
```js
const { BrowserWindow, Menu} = require('electron')
const template = [
{
label: '文件',
submenu: [
{
label: '新建窗口',
click: ()=>{
const newMainWindow = new BrowserWindow({
width: 300,
height: 300
})
newMainWindow.loadFile('./new.html')
}
}
]
},
{
label: '编辑',
submenu: [
{
label: '新建窗口'
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
```
```js
require('./menu')
```
#### 打开调式
mainWindow.webContents.openDevTools()
#### 自定义顶部菜单
+ 通过BrowserWindow.frame创建无边框窗口
+ 自定义窗口
```html
```
+ icon
+ backgroundColor
#### 定义右键菜单
js>index.js
```js
const { remote } = require('electron')
const template = [
{
label: '粘贴'
},
{
label: '赋值'
}
]
const menu = remote.Menu.buildFromTemplate(template)
window.addEventListener('contextmenu', (e) => {
console.log(123)
e.preventDefault()
menu.popup({ window: remote.getCurrentWindow() })
})
```
在index.html中引入
```js
Document
```
能够在html中使用node方法
```js
const mainWindow = new BrowserWindow({
width: 800,
height: 500,
webPreferences: {
nodeIntegration: true
}
})
```
#### 点击打开浏览器
+ html
```html
打开浏览器
```
+ js
```js
const { shell } = require('electron')
const aEL = document.querySelector('#a1')
aEL.onclick = function(e) {
e.preventDefault()
const url = this.getAttribute('href')
shell.openExternal(url)
}
```
#### 自动刷新页面
+ 安装插件
```js
cnpm install --save-dev electron-reloader
```
+ 在入口引入插件
```js
const reloader = require('electron-reloader')
reloader(module,{})
```
#### 拖拽文件进行读取
+ 定义拖拽到指定区域
```html
```
```css
#drop {
width: 300px;
height: 500px;
background: hotpink;
}
```
+ 添加拖拽事件获取文件路径
```js
// 添加拖拽
const dropEl = document.querySelector('#drop')
dropEl.addEventListener('drop', function(e) {
if(e.dataTransfer.files.length === 1) {
const filePath = e.dataTransfer.files[0].path
}
})
dropEl.addEventListener('dragover', function (e) {
e.preventDefault()
})
```
+ 引入fs模块进行读取
```js
const fs = require('fs')
// 添加拖拽
const dropEl = document.querySelector('#drop')
dropEl.addEventListener('drop', function(e) {
if(e.dataTransfer.files.length === 1) {
const filePath = e.dataTransfer.files[0].path
const fileContent = fs.readFileSync(filePath).toString()
this.innerText = fileContent
}
})
dropEl.addEventListener('dragover', function (e) {
e.preventDefault()
})
```
#### 打开对话框
##### 读取文件
+ 定义点击事件
```js
```
+ 定义事件函数
```js
// 打开对话框
function openFile() {
const res = remote.dialog.showOpenDialogSync({
title: '选择文件',
buttonLabel: '哈哈',
filters: [
{ name: 'Custom File Type', extensions: ['js','html','json'] },
]
})
const fileContent = fs.readFileSync(res[0]).toString()
dropEl.innerText = fileContent
}
```
##### 保存文件
+ 定义点击事件
```html
```
+ 事件函数
```js
// 保存对话框
function saveFile() {
const res = remote.dialog.showSaveDialogSync({
title: '保存文件',
buttonLabel: '保存文件',
filters: [
{ name: 'index', extensions: ['js'] },
]
})
fs.writeFileSync(res, 'hahhdasdshafsdahjk')
}
```
##### 消息提示
+ 定义事件
```html
```
+ 事件函数
```js
// 提示信息
function messageBox() {
remote.dialog.showMessageBoxSync({
type: 'none',
buttons: ['确定'],
title: '提示消息',
message: '明天会下雨呦'
})
}
```
#### 定义快捷键
##### 主线程定义
+ 引入
```js
const { app, BrowserWindow, globalShortcut } = require('electron')
```
+ 在ready中注册快捷键
```js
const { app, BrowserWindow, globalShortcut } = require('electron')
```
##### 渲染进程定义
+ 通过remote注册
```js
// 定义快捷键
remote.globalShortcut.register('Ctrl+O', () => {
console.log('ctrl+o')
})
```
+ 定义快捷键最大、最小、关闭窗口
```js
globalShortcut.register('Ctrl+T',()=>{
mainWindow.unmaximize();
})
globalShortcut.register('Ctrl+H',()=>{
mainWindow.close()
})
globalShortcut.register('Ctrl+M',()=>{
mainWindow.maximize()
})
```
#### 渲染进程和主线程通讯
+ 定义按钮
```html
```
+ 事件函数
```js
function maxWindow() {
ipcRenderer.send('max-window')
}
```
+ 主线程定义事件
```js
ipcMain.on('max-window', () => {
mainWindow.maximize()
})
```
+ 传参
```js
let windowSize = 'unmax-window'
function maxWindow() {
windowSize = windowSize === 'max-window' ?'unmax-window':'max-window'
ipcRenderer.send('max-window',windowSize)
}
```
+ 接收参数
```js
ipcMain.on('max-window', (event,arg) => {
console.log(arg)
if(arg === 'unmax-window') return mainWindow.maximize();
mainWindow.unmaximize()
})
```
+ 通过isMaximized判断当前窗口
#### 网络请求
```js
async function getMsg () {
const res = await fetch('http://127.0.0.1:3006/api/person').then(res=>res.json())
console.log(res)
}
```
#### electron结合react
##### 利用react初始化项目
+ npx create-react-app electron-react
+ cd electron-react
+ npm start
##### 安装electron
+ cnpm i electron
+ 添加electron的任务
```js
"main": "main.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')
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600
})
// Open the DevTools.
// mainWindow.webContents.openDevTools()
}
app.whenReady().then(() => {
createWindow()
})
```
+ 加载react项目
```js
mainWindow.loadURL('http://localhost:3000/')
```
#### electron结合vue
同react
#### electron打包
+ 将vue项目打包
+ 修改electron引入的文件
```js
mainWindow.loadFile('./dist/index.html')
```
+ 安装electron-packager
```js
"packager": "electron-packager ./ HelloWorld --platform=win32 --arch=x64 --out ./outApp --overwrite --icon=./favicon.ico"
```