Electron的使用技巧

官方网站: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) 模块进行:ipcMainipcRenderer

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);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Electron 中,可以使用 remote 模块访问主进程中的模块和函数。这种机制可以方便地从渲染进程中调用主进程的功能,同时也可以避免在渲染进程中直接访问 Node.js 模块。 以下是一些 remote 模块的使用技巧: 1. 导入 remote 模块 在渲染进程中,需要先导入 remote 模块,才能访问主进程中的模块和函数。可以使用以下代码导入: ```javascript const { remote } = require('electron'); ``` 2. 访问主进程中的模块和函数 可以使用 remote 模块访问主进程中的模块和函数。例如,可以通过以下代码访问主进程中的 app 模块: ```javascript const { app } = remote; ``` 同样的,也可以通过以下代码访问主进程中的自定义模块: ```javascript const customModule = remote.require('./custom_module'); ``` 3. 在渲染进程中创建窗口 可以使用 remote 模块在渲染进程中创建新的窗口。例如,可以通过以下代码在渲染进程中创建新的浏览器窗口: ```javascript const { BrowserWindow } = remote; const newWindow = new BrowserWindow({ width: 800, height: 600 }); newWindow.loadURL('https://www.example.com'); ``` 需要注意的是,使用 remote 模块创建的窗口仍然是在主进程中创建的,因此需要在主进程中设置相应的权限和安全策略。 4. 在渲染进程中操作菜单和对话框 可以使用 remote 模块在渲染进程中操作菜单和对话框。例如,可以通过以下代码在渲染进程中弹出一个消息框: ```javascript const { dialog } = remote; dialog.showMessageBox({ message: 'Hello, world!' }); ``` 同样的,也可以在渲染进程中操作菜单。例如,可以通过以下代码在渲染进程中添加一个菜单项: ```javascript const { Menu } = remote; const newMenu = Menu.buildFromTemplate([ { label: 'New Item', click: () => console.log('New item clicked'), }, ]); Menu.setApplicationMenu(newMenu); ``` 需要注意的是,在渲染进程中操作菜单和对话框时,需要在主进程中设置相应的菜单和对话框模板。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值