electron实现桌面应用
1. 简介
- 官网
- Electron是由GitHub开发,使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序
- Electron 可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造桌面应用。你可以把它看作是专注于桌面应用
- 在PC端混合app开发中,nwjs和electron都是可选的方案,它们都是基于Chromium和Node的结合体, 而electron相对而言是更好的选择方案,它的社区相对比较活跃,bug比较少,文档先对利索简洁。
- electron 相对来说比 nw.js 靠谱。有一堆成功的案例:Atom 编辑器 2. Slack (那个独角兽公司)3. Visual Studio Code 4. WordPress 等等。。
- Node. js 的所有 内置模块 都在Electron中可用, 第三方 node 模块中也完全支持 (包括 原生模块 )。
- Electron 还为开发原生桌面应用程序提供了一些额外的内置模块。 某些模块仅在主进程中可用, 有些仅在渲染进程 (web 页) 中可用, 而有些在这两个进程中都可以使用。
2. 五分钟快速上手
2.1 安装electron
- npm init
- cnpm I electron –S
- npx electron
2.2 配置为入口文件
{
"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"
}
}
2.3 创建main.js文件
const electron = require('electron')
const app = electron.app
app.on('ready', ()=>{
new electron.BrowserWindow({
width: 800,
height: 300
})
})
2.4创建窗口
app.on('ready', ()=>{
const mainWindow = new BrowserWindow({
width: 800,
height: 500
})
mainWindow.loadFile('./index.html')
})
3. 主进程和渲染进程
Electron 运行 package.json
的 main
脚本的进程被称为主进程。 在主进程中运行的脚本通过创建web页面来展示用户界面。 一个 Electron 应用总是有且只有一个主进程。
由于 Electron 使用了 Chromium 来展示 web 页面,所以 Chromium 的多进程架构也被使用到。 每个 Electron 中的 web 页面运行在它的叫渲染进程的进程中。
在普通的浏览器中,web页面无法访问操作系统的原生资源。 然而 Electron 的用户在 Node.js 的 API 支持下可以在页面中和操作系统进行一些底层交互。
ctrl+shift+i打开渲染进程调试
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')
})
4. 自定义原生菜单
4.1 自定义菜单
const electron = require('electron')
const { app, Menu } = electron
const template = [
{
label: '文件',
submenu: [
{
label: '新建窗口'
}
]
},
{
label: '编辑',
submenu: [
{
label: '新建窗口'
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
4.2 给菜单定义点击事件
1、点击打开新窗口
submenu: [
{
label: '新建窗口',
click: ()=>{
const newMainWindow = new BrowserWindow({
width: 300,
height: 300
})
newMainWindow.loadFile('./new.html')
}
}
]
2、点击打开浏览器
const { BrowserWindow, Menu, shell } = require('electron')
const template = [
{
label: '文件',
submenu: [
{
label: '文件1',
click () {
// 点击打开新窗口
const mainWindow2 = new BrowserWindow({
width: 600,
height: 600
})
mainWindow2.loadFile('./index.html')
}
}
]
},
{
label: 'csdn',
click () {
// 点击打开浏览器
shell.openExternal('https://www.csdn.net/')
}
}
]
4.3 抽离菜单定义
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)
require('./menu')
打开调式
mainWindow.webContents.openDevTools()
4.4 自定义顶部菜单
-
通过frame创建无边框窗口
const mainWindow = new electron.BrowserWindow({ frame: false })
-
自定义窗口
<div class="header" style="-webkit-app-region: drag;"> </div>
-
icon
const mainWindow = new electron.BrowserWindow({ width: 1000, height: 600, webPreferences: { nodeIntegration: true }, frame: false, icon: './hm.ico' })
-
backgroundColor
4.5 定义右键菜单
js>index.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中引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button>打开新的窗口</button>
<script src="./js/index.js"></script>
</body>
</html>
能够在html中使用node方法
const mainWindow = new BrowserWindow({
width: 800,
height: 500,
webPreferences: {
nodeIntegration: true
}
})
4.6 点页面打开浏览器
-
html
<a id="a1" href="https://blog.csdn.net/weixin_41819098">打开浏览器</a>
-
js
const { shell } = require('electron') const allA = document.querySelectorAll('a') allA.forEach(item => { item.onclick = function (e) { e.preventDefault() console.log(item) shell.openExternal(item.href) } })
5. 自动刷新页面
-
安装插件
cnpm install --save-dev electron-reloader
-
在入口引入插件
const reloader = require('electron-reloader') reloader(module,{})
6. 拖拽文件进行读取
-
定义拖拽到指定区域
<div id="drop"> </div>
#drop { width: 300px; height: 500px; background: hotpink; }
-
添加拖拽事件获取文件路径
// 添加拖拽 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模块进行读取
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() })
7. 打开对话框
7.1 读取文件
-
定义点击事件
<button onclick="openFile()">打开</button>
-
定义事件函数
// 打开对话框 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 }
7.2 保存文件
-
定义点击事件
<button onclick="saveFile()">保存</button>
-
事件函数
// 保存对话框 function saveFile() { const res = remote.dialog.showSaveDialogSync({ title: '保存文件', buttonLabel: '保存文件', filters: [ { name: 'index', extensions: ['js'] }, ] }) fs.writeFileSync(res, 'hahhdasdshafsdahjk') }
8. 消息提示
-
定义事件
<button onclick="messageBox()">提示</button>
-
事件函数
// 提示信息 function messageBox() { remote.dialog.showMessageBoxSync({ type: 'none', buttons: ['确定'], title: '提示消息', message: '明天会下雨呦' }) }
9. 定义快捷键
9.1 主线程定义
-
引入
const { app, BrowserWindow, globalShortcut } = require('electron')
-
在ready中注册快捷键
const { app, BrowserWindow, globalShortcut } = require('electron')
9.2 渲染进程定义
-
通过remote注册
// 定义快捷键 remote.globalShortcut.register('Ctrl+O', () => { console.log('ctrl+o') })
-
定义快捷键最大、最小、关闭窗口
globalShortcut.register('Ctrl+T',()=>{ mainWindow.unmaximize(); }) globalShortcut.register('Ctrl+H',()=>{ mainWindow.close() }) globalShortcut.register('Ctrl+M',()=>{ mainWindow.maximize() })
10. 渲染进程和主线程通讯
-
定义按钮
<div class="maxWindow no-drag" onclick="maxWindow()"></div>
-
事件函数
function maxWindow() { ipcRenderer.send('max-window') }
-
主线程定义事件
ipcMain.on('max-window', () => { mainWindow.maximize() })
-
传参
let windowSize = 'unmax-window' function maxWindow() { windowSize = windowSize === 'max-window' ?'unmax-window':'max-window' ipcRenderer.send('max-window',windowSize) }
-
接收参数
ipcMain.on('max-window', (event,arg) => { console.log(arg) if(arg === 'unmax-window') return mainWindow.maximize(); mainWindow.unmaximize() })
-
通过isMaximized判断当前窗口
11. 网络请求
async function getMsg () {
const res = await fetch('http://127.0.0.1:3006/api/person').then(res=>res.json())
console.log(res)
}
12 .electron结合框架开发
12.1 结合react
利用react初始化项目
- npx create-react-app electron-react
- cd electron-react
- npm start
安装electron
-
cnpm i electron
-
添加electron的任务
"main": "main.js", "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "electron": "electron ." },
-
添加main.js https://github.com/electron/electron-quick-start/blob/master/main.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项目
mainWindow.loadURL('http://localhost:3000/')
12.2 electron结合vue
同react
13 electron打包
-
将vue项目打包
-
修改electron引入的文件
mainWindow.loadFile('./dist/index.html')
-
安装electron-packager
"packager": "electron-packager ./ HelloWorld --platform=win32 --arch=x64 --out ./outApp --overwrite --icon=./favicon.ico"
更多推荐
所有评论(0)