赞
踩
官方网站:https://www.electronjs.org/
开发文档:https://www.electronjs.org/docs
开发API:https://www.electronjs.org/zh/docs/latest/api/app
注意:如果用的是最新的electron,应该看最新的文档,有可能出现api不兼容的问题。
Electron 基于 Chromium 和 Node.js, 让你可以使用 HTML, CSS 和 JavaScript 构建跨平台桌面应用。Electron 兼容 Mac、Windows 和 Linux,可以构建出三个平台的应用程序。
懂前端的同学学习electron上手很快。VScode,Whatsapp等都是使用electron开发。
打开scode,创建一个项目,使用终端执行 npm i -D electron@latest。使用yarn也可以。
配置文件:项目根目录下 package.json
{ "name": "electron", "version": "1.0.0", "description": "高效工具", "main": "main.js", "scripts": { "start": "chcp 65001 && electron .", "build": "electron-builder ." }, "build": { "appId": "win.electron.com", "asar": "false", "win": { "icon": "logo.ico" } }, "author": "andy", "license": "ISC", "devDependencies": { "electron": "^7.0.0", "electron-builder": "^21.2.0" }, "dependencies": { "iconv-lite": "^0.5.0", "uglify-js": "^3.6.2", "xmldom": "^0.1.27" } }
运行方法:按F5或者 在终端执行 npm run start
发布方法:在终端执行 npm run build
Electron 包含三个核心:
1.Chromium 用于显示网页内容。
2.Node.js 用于本地文件系统和操作系统。
3.自定义 APIs 用于使用经常需要的 OS 本机函数。
用 Electron 开发应用程序就像构建一个带有网页界面的 Node.js 应用程序或构建无缝集成的网页。Electron 有两种进程:主进程和渲染进程。Html以及通过网页引入的js即可理解为渲染进程。
主进程通过创建 BrowserWindow 实例来创建 网页。 每一个 BrowserWindow 实例在其渲染过程中运行网页, 当一个 BrowserWindow 实例被销毁时,对应的渲染过程也会被终止。主进程 管理 所有网页及其对应的渲染进程。
渲染进程只能管理相应的网页, 一个渲染进程的崩溃不会影响其他渲染进程。渲染进程通过 IPC 与主进程通信在网在页上执行 GUI 操作。 出于安全和可能的资源泄漏考虑,直接从渲染器进程中调用与本地 GUI 有关的 API 受到限制。
进程之间的通信可以通过 Inter-Process Communication(IPC) 模块进行:ipcMain 和 ipcRenderer
3.1常见方法:
const {BrowserWindow,app,ipcRenderer } = require('electron'); //项目根目录绝对路径 app.getAppPath() //当前文件的绝对路径 __dirname //BrowserWindow 配置 //是否启用node 禁用后,渲染层无法使用node nodeIntegration: true, //是否上下文隔离 隔离后,渲染层不可访问某些类,比如:ipcRenderer contextIsolation:false, //是否可远程加载模块 禁用后,渲染层将无法使用require方法 enableRemoteModule:true, //
3.2contextIsolation设置
electron建议为了安全,启用上下文隔离,将contextIsolation设置为true。隔离后主进程与渲染层,可以这样通讯:
//1.main.js const mainWindow = new BrowserWindow({ webPreferences: { preload: path.join(__dirname, 'preload.js') } }) ipcMain.on('set-title', (event, title) => { const webContents = event.sender const win = BrowserWindow.fromWebContents(webContents) win.setTitle(title) }) mainWindow.loadFile('index.html') //2.preload.js const { contextBridge, ipcRenderer } = require('electron') contextBridge.exposeInMainWorld('electronAPI', { setTitle: (title) => ipcRenderer.send('set-title', title) }) //3.render.js setButton.addEventListener('click', () => { const title = titleInput.value window.electronAPI.setTitle(title) })
如果没有隔离,主进程与渲染层,可以这样通讯:
//1.main.js
ipcMain.on('login', (event, data) => {
//获得登录数据
data.name data.pass
})
//2.render.js
btn.addEventListener('click',(e)=>{
ipcRenderer.send("login",{name:'andy',pass:"123"});
});
3.3如何打包:
npm install --save-dev @electron-forge/cli
npx electron-forge import
npm run make
打包出错:
An unhandled rejection has occurred inside Forge:
RequestError: Socket connection timeout
项目根目录创建文件:.npmrc
增加内容:electron_mirror=https://npmmirror.com/mirrors/electron/
4.1 main.js
const electron=require('electron'); //主进程 const ipcMain =electron.ipcMain; const dialog=electron.dialog; const webContents = electron.webContents; const cp=require("child_process"); const { app, BrowserWindow,Menu } = require('electron') const path = require('path') // 保持对window对象的全局引用,如果不这么做的话,当JavaScript对象被 // 垃圾回收的时候,window对象将会自动的关闭 let win function createWindow () { // 创建浏览器窗口。 win = new BrowserWindow({ width: 376, height: 728, minWidth:360, minHeight:640, resizable:true, movable:true, title:"工具", icon:path.join(__dirname, 'logo.ico'), webPreferences: { nodeIntegration: true, contextIsolation:false } }) //显示主菜单 win.setMenu(null); win.webContents.on('context-menu', function (e, params) { menu.popup(win, params.x, params.y); console.log(e); }) // 加载index.html文件 win.loadFile('index.html') // 打开开发者工具 //win.webContents.openDevTools(); global.mainWindow=win; // 当 window 被关闭,这个事件会被触发。 win.on('closed', () => { // 取消引用 window 对象,如果你的应用支持多窗口的话, // 通常会把多个 window 对象存放在一个数组里面, // 与此同时,你应该删除相应的元素。 win = null }) } // Electron 会在初始化后并准备 // 创建浏览器窗口时,调用这个函数。 // 部分 API 在 ready 事件触发后才能使用。 app.on('ready', createWindow) // 当全部窗口关闭时退出。 app.on('window-all-closed', () => { // 在 macOS 上,除非用户用 Cmd + Q 确定地退出, // 否则绝大部分应用及其菜单栏会保持激活。 if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', () => { // 在macOS上,当单击dock图标并且没有其他窗口打开时, // 通常在应用程序中重新创建一个窗口。 if (win === null) { createWindow() } })
4.2 index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title>工具</title> <style> body{ margin: 0px; padding: 0px; } </style> </head> <body> <div> <input id="btnOpenProj" type="button" value="菜单1" /> <input id="btnLookProj" type="button" value="菜单2" title="菜单2"/> <input id="btnLookProj" type="button" value="菜单3" title="菜单3"/> </div> <script>require("./render.js")</script> </body> </html>
4.3 render.js
const electron = require('electron'); //渲染进程 const render = electron.ipcRenderer; //主进程 const remote = electron.remote; //菜单 var template = [ { label: '图片', submenu: [{ id:'btnImage1', label: '图片1', click:clickMenu }, { id:'btnImage2', label: '图片2', click:clickMenu }] }, { label: '音乐', submenu: [{ id:'btnMusic1', label: '音乐1', click:clickMenu },{ id:'btnMusic2', label: '音乐2', click:clickMenu }] }]; let topMenu=Menu.buildFromTemplate(template); Menu.setApplicationMenu(topMenu); //菜单点击事件 function clickMenu(menuItem,win,event){ console.log("点击菜单:",menuItem.id,menuItem.label); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。