electron的学习基础汇总

通过学习electron了解一下做项目中好奇的问题,我觉得下面这张图就可以说明一切了,就是在初次创建并显示主窗口后,一切都将建立在渲染进程和主进程的通信上,而用的技术就是ipcMain和ipcRender,那么渲染进程如何与主进程建立连接的桥梁,就涉及contextBridge,然后通过exposeInMainWorld()将API注入到window,就可全局访问。

因为已经写过截图和富文本编辑功能了,等后期再做这类的文章总结,主要目前时间不够,所以慢慢来吧。

标题electron工作流程

主进程:

可以看作是package.json中的main属性对应文件

一个应用只会有一个主进程

只有主进程可以进行GUI的API操作
渲染进程:

windows中展示的界面通过渲染进程表现

一个应用可以有多个渲染进程
整体流程:

启动主进程,创建窗口

加载指定界面

开启渲染进程,若渲染进程要进行通讯就需要IPC来完成进程间的操作
electron环境搭建

electron + react搭建的框架已经搭建完成来,所以省略搭建的总结文章,可以直接github上拿代码。

标题electron 加载app

启动app

app.whenReady().then(() => {
    // 创建window
    const mainWin = new BroBrowserWindow({})
    
    // loadFile加载指定的界面显示
    mainWin.loadFile('')
    
    mainWin.on('close|hide|move|minimize')
})
app.on('window-all-close', () => { ... })

标题electron生命周期

ready: app初始化完成

dom-ready: 一个窗口中的文本加载完成

did-finish-load:导航完成时触发

window-all-closed:所有窗口都被关闭时触发

before-quit:在关闭窗口之前触发

will-quit:在窗口关闭并且应用退出时触发

quit:当所有窗口被关闭时触发

closed:当窗口关闭时触发,此时应删除窗口引用

标题electron BrowserWindow参数修改

官网此API地址

mainWindow = new BrowserWindow({
    show: false,
    width: 1024,
    height: 728,
    // min|max -width|height来设置窗口的最大值或最小值
    minWidth: 700,
    minHeight: 570,
    // icon:作用在window窗口左上角的小logo,mac不显示,linux暂不清楚,支持png、jpg、ico格式
    icon: getAssetPath('logo.png'),
    // title:窗口标题作用在window和mac上,linux暂不清楚
    title: "横截面",
    // frame:默认为true,设置为false就是将默认的菜单栏menu隐藏,可以自定义menu
    frame: false,
    // transparent: true, // 窗口透明 默认false. 在Windows上,仅在无边框窗口下起作用。
    // // 自动隐藏菜单栏,除非按了Alt键。 默认值为 false.
    // autoHideMenuBar: true,
    webPreferences: {
      preload: app.isPackaged
        ? path.join(__dirname, 'preload.js')
        : path.join(__dirname, '../.erb/dll/preload.js'),
    },
  });
  mainWindow.loadURL(resolveHtmlPath(''));

要是在主窗口想和渲染窗口进行交互,则通过ipcMain和ipcRender来实现新窗口

ipcMain: 从主进程到渲染进程的异步通信。

ipcRender:是一个 EventEmitter 的实例。 当在主进程中使用时,它处理从渲染器进程(网页)发送出来的异步和同步信息。 从渲染器进程发送的消息将被发送到该模块。

标题electron 创建子窗口

// 引入
import { createAt } from './views/at'
createAt(mainWindow)

import { BrowserWindow } from "electron"
import { getAssetPath } from '../utils/path'

export const createAt = (main: BrowserWindow) => {
  const createAtWindow = new BrowserWindow({
    show: false,
    width: 1024,
    height: 728,
    title: '@窗口',
    minWidth: 700,
    minHeight: 570,
    icon: getAssetPath('logo.png'),
  })
  
  // 当主窗口加载好了,再显示at窗口
  main.on('ready-to-show', () => {
    if (process.env.START_MINIMIZED) {
      createAtWindow.minimize();
    } else {
      createAtWindow.show();
    }
  })
}

标题electron 阻止窗口关闭

macos系统通知设置了,但并未显示,这块儿还得进行调整

标题electron 自定义托盘样式

/**
 * 给程序增加托盘样式图标
 */
app.on('ready', () => {
  let appIcon = new Tray(path.join(__dirname, '../assets/tray.png'))
  const contextMenu = Menu.buildFromTemplate([
    { label: '退出', accelerator: 'Cmd+Q', click: () => {  app.exit() } }
  ])
  appIcon.setContextMenu(contextMenu)
})

标题electron 托盘及菜单

托盘这块儿,主要要学习的就是右击显示菜单,点击将主屏幕显示在最上面的窗口上

/** 托盘文件内容  **/
import { BrowserWindow, Menu, Tray, app, nativeImage } from "electron";
import { getAssetPath } from "../utils/path";

// 托盘小图标
const applicationImage = (path: any) =>
  nativeImage.createFromPath(path).resize({ width: 18, height: 18 });
// 获取图标路径
const trayIcon = getAssetPath('tray.png');

export const createTray = (main: BrowserWindow) => {
  /** 根据托盘所需的大小重绘 */
  let tray = new Tray(applicationImage(trayIcon))

  const menuOption = [
    { label: '退出', accelerator: 'Cmd+Q', click: () => {  app.exit() } }
  ]
  const contextMenu = Menu.buildFromTemplate(menuOption)
  /** 使用setContextMenu要慎重,因为这是设置默认行为的,要是右击,需要使用popUpContextMenu */
  // tray.setContextMenu(contextMenu);

  /**
   * 点击,显示主窗口
   */
  tray.on('click', () => {
    if(!main.isDestroyed()) main.show();
  })

  /**
   * 右击,显示菜单
   */
  tray.on('right-click', (e) => {
    tray.popUpContextMenu(contextMenu)
  })
}

标题electron的dialog

主进程
import { app, BrowserWindow, shell, ipcMain, Notification, dialog} from 'electron';
/**
 * 下载
 */
ipcMain.on(MainEnums.DOWNLOAD, () => {
  dialog.showOpenDialog({
    title: '请选择下载路径',
    defaultPath: app.getPath('downloads'),
    properties: ['openDirectory', 'createDirectory']
  }).then((res) => {
    if(res.filePaths) {
      store.set('downloadPath', res.filePaths)
    }
  })
})
/**
* 调用下载
*/
ipcRenderer.send(MainEnums.DOWNLOAD)

标题electron app dock使用

main.ts文件中的app使用dock
/**
 * Add event listeners...
 */

if(isMac) {
  const dockIcon = applicationImage({path: 'dockIcon.png'})
 
  // 获取图标路径
  app.dock.setIcon(dockIcon)
}
main.ts文件中所使用的applicationImage封装方法,我写在utils/path.ts内:
const RESOURCES_PATH = app.isPackaged
  ? path.join(process.resourcesPath, 'assets')
  : path.join(__dirname, '../../assets');

export const getAssetPath = (...paths: string[]): string => {
  return path.join(RESOURCES_PATH, ...paths);
};

// dock图标和托盘小图标共用
export const applicationImage = ({path, size}: PathType['image']) =>{
  return nativeImage.createFromPath(getAssetPath(path)).resize({ ...size })
};

electron配置打包:

参考:https://juejin.cn/post/7009179524520738824

持续更新中。。。

相关推荐
酷酷的阿云5 分钟前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
lulu_gh_yu27 分钟前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
Re.不晚1 小时前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
aPurpleBerry1 小时前
JS常用数组方法 reduce filter find forEach
javascript
ZL不懂前端2 小时前
Content Security Policy (CSP)
前端·javascript·面试
乐闻x2 小时前
ESLint 使用教程(一):从零配置 ESLint
javascript·eslint
幼儿园老大*2 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
2 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
ctrey_2 小时前
2024-11-4 学习人工智能的Day21 openCV(3)
人工智能·opencv·学习
我血条子呢2 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js