当前位置: 首页 > news >正文

vue vite ts electron ipc arm64

初始化

npm init vue # 全选 yes
npm i # 进入项目目录后使用
npm install electron electron-builder -D
npm install commander -D # 额外组件

增加文件

新建 plugins 文件夹

src/background.ts

属于主进程

ipcMain.on、ipcMain.handle 都用于主进程监听 ipc,ipcMain.on 用于监听 ipcRenderer.send,ipcMain.handle 用于监听 ipcRenderer.invoke 并 return xxx

ipc 单向:
从渲染进程发向主进程:ipcRenderer.send
从主进程发向渲染进程:window.webContents.send

ipc 双向:
从渲染进程发向主进程,主进程还会返回发向渲染进程:ipcRenderer.invoke
从主进程发向渲染进程,渲染进程还会返回发向主进程:没有类似于 ipcRenderer.invoke 的,需要间接实现。主进程使用 window.webContents.send,渲染进程使用 ipcRenderer.send

import { app, BrowserWindow, screen, ipcMain } from 'electron'
import path from 'path'
import { Command } from 'commander';app.whenReady().then(() => {const command = new Commandlet width, heightlet optionscommand.option('-m, --maximize', 'maximize window').option('-l, --location <>', 'location of load index page', 'index.html').option('-d, --dev', 'openDevTools').option('--no-sandbox', 'other').parse()options = command.opts()if (options.maximize) {width = screen.getPrimaryDisplay().workAreaSize.widthheight = screen.getPrimaryDisplay().workAreaSize.height}else {width = 800height = 600}const window = new BrowserWindow({width: width,height: height,autoHideMenuBar: true,webPreferences: {preload: path.join(__dirname, 'preload.js')}})if (options.location.indexOf(':') >= 0)window.loadURL(options.location)elsewindow.loadFile(options.location)if (options.dev)window.webContents.openDevTools()ipcMain.on('rtm', () => {console.log('rtm')window.webContents.send('mtr')})ipcMain.on('rtm_p', (e, p) => {console.log(p)window.webContents.send('mtr_p', `mtr_p ${p}`)})ipcMain.handle('rtmmtr_p', (e, p) => {console.log(p)return 'rtmmtr_p_return'})
})

src/preload.ts

预加载脚本,用来给渲染进程提供使用 ipcRenderer 的方法
rtm 是渲染进程发向主进程;rtmmtr 是从渲染进程发向主进程,主进程还会返回发向渲染进程;mtr 是主进程发向渲染进程

import { contextBridge, ipcRenderer } from 'electron'contextBridge.exposeInMainWorld('electronAPI', {rtm: () => ipcRenderer.send('rtm'),rtm_p: (p: any) => ipcRenderer.send('rtm_p', p),rtmmtr_p: (p: any) => ipcRenderer.invoke('rtmmtr_p', p),mtr: (p: any) => ipcRenderer.on('mtr', p),mtr_p: (p: any) => ipcRenderer.on('mtr_p', p),
})

src/renderer.d.ts

给渲染进程用的 preload.ts 里的方法的类型声明

export interface IElectronAPI {rtm: () => Promise<any>,rtm_p: (p: any) => Promise<any>,rtmmtr_p: (p: any) => Promise<any>,mtr: (p: any) => Promise<any>,mtr_p: (p: any) => Promise<any>,
}declare global {interface Window {electronAPI: IElectronAPI}
}

plugins/vite.electron.dev.ts

自定义 dev 方法,用于启动 vite 后带起 electron

// 导入需要使用的类型和库
import type { Plugin } from 'vite'
import type { AddressInfo } from 'net'
import { spawn } from 'child_process'
import fs from 'fs'// 导出Vite插件函数
export const viteElectronDev = (): Plugin => {return {name: 'vite-electron-dev',// 在configureServer中实现插件的逻辑configureServer(server) {// 定义初始化Electron的函数const initElectron = () => {// 使用esbuild编译TypeScript代码为JavaScriptrequire('esbuild').buildSync({entryPoints: ['src/background.ts', 'src/preload.ts'],bundle: true,outdir: 'dist',platform: 'node',external: ['electron']})}// electron 运行let electron_run = (ip: string) => {initElectron()// 启动Electron进程let electronProcess = spawn(require('electron'), ['dist/background.js', '-l', ip, '-d'])// 监听Electron进程的stdout输出electronProcess.stdout?.on('data', (data) => {console.log(`${data}`);});return electronProcess}// 监听Vite的HTTP服务器的listening事件server?.httpServer?.once('listening', () => {// 获取HTTP服务器的监听地址和端口号const address = server?.httpServer?.address() as AddressInfoconst ip = `http://localhost:${address.port}`let electronProcess = electron_run(ip)// 监听主进程代码的更改fs.watch('src', () => {// 杀死当前的Electron进程electronProcess.kill()electronProcess = electron_run(ip)})})}}
}

plugins/vite.electron.build.ts

自定义 build 方法,这里打包了 linux 的 x64、arm64 的包

import type { Plugin } from 'vite'
import * as electronBuilder from 'electron-builder'
import path from 'path'
import fs from 'fs'// 导出Vite插件函数
export const viteElectronBuild = (): Plugin => {return {name: 'vite-electron-build',// closeBundle是Vite的一个插件钩子函数,用于在Vite构建完成后执行一些自定义逻辑。closeBundle() {// 定义初始化Electron的函数const initElectron = () => {// 使用esbuild编译TypeScript代码为JavaScriptrequire('esbuild').buildSync({entryPoints: ['src/background.ts', 'src/preload.ts'],bundle: true,outdir: 'dist',platform: 'node',external: ['electron']})}// 调用初始化Electron函数initElectron()// 修改package.json文件的main字段,不然会打包失败const json = JSON.parse(fs.readFileSync('package.json', 'utf-8'))json.main = 'background.js'fs.writeSync(fs.openSync('dist/package.json', 'w'), JSON.stringify(json, null, 2))// 创建一个空的node_modules目录 不然会打包失败fs.mkdirSync(path.join(process.cwd(), "dist/node_modules"));// 使用electron-builder打包Electron应用程序electronBuilder.build({config: {appId: 'com.example.app',productName: 'vite-electron',directories: {output: path.join(process.cwd(), "release"), //输出目录app: path.join(process.cwd(), "dist"), //app目录},linux: {"target": [{"target": "AppImage","arch": ["x64", "arm64"]}]}}})}}
}

修改源文件

src/App.vue

属于渲染进程

window.electronAPI.xxx() 就是预加载脚本(preload.ts)给渲染进程提供的使用 ipcRenderer 的方法
window.electronAPI.mtr 和 …mtr_p (mtr:main to renderer)用于监听主进程发过来的消息
由于 window.electronAPI.rtmmtr_p 使用 ipcRenderer.invoke,这是异步方法,如果不在其前面加 await 而直接获取会得到一个用于异步执行的对象(Promise),其内容包含了需要异步执行的东西,await 就是等待该对象运行结束从而获取正确值,而 await 需要其调用者是异步的,所以 increment() 也加上了 async(异步标志)

<script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
import { ref } from 'vue'// 响应式状态
const count = ref(0)// 用来修改状态、触发更新的函数
async function increment() {count.value++window.electronAPI.rtm()window.electronAPI.rtm_p(`rtm_p ${count.value}`)const rtmmtr_p = await window.electronAPI.rtmmtr_p(`rtmmtr_p ${count.value}`)console.log(rtmmtr_p)
}window.electronAPI.mtr(() => {console.log('mtr')
})window.electronAPI.mtr_p((e: any, p: any) => {console.log(p)
})
</script><template><button @click="increment">hhh: {{ count }}</button><header><img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" /><div class="wrapper"><HelloWorld msg="You did it!" /><nav><RouterLink to="/">Home</RouterLink><RouterLink to="/about">About</RouterLink></nav></div></header><RouterView />
</template><style scoped>
header {line-height: 1.5;max-height: 100vh;
}.logo {display: block;margin: 0 auto 2rem;
}nav {width: 100%;font-size: 12px;text-align: center;margin-top: 2rem;
}nav a.router-link-exact-active {color: var(--color-text);
}nav a.router-link-exact-active:hover {background-color: transparent;
}nav a {display: inline-block;padding: 0 1rem;border-left: 1px solid var(--color-border);
}nav a:first-of-type {border: 0;
}@media (min-width: 1024px) {header {display: flex;place-items: center;padding-right: calc(var(--section-gap) / 2);}.logo {margin: 0 2rem 0 0;}header .wrapper {display: flex;place-items: flex-start;flex-wrap: wrap;}nav {text-align: left;margin-left: -1rem;font-size: 1rem;padding: 1rem 0;margin-top: 1rem;}
}
</style>

修改配置文件

tsconfig.node.json

{"extends": "@tsconfig/node18/tsconfig.json","include": ["vite.config.*","vitest.config.*","cypress.config.*","nightwatch.conf.*","playwright.config.*","plugins/**/*.ts"],"compilerOptions": {"composite": true,"module": "ESNext","types": ["node"]}
}

vite.config.ts

import { fileURLToPath, URL } from 'node:url'import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import { viteElectronDev } from './plugins/vite.electron.dev'
import { viteElectronBuild } from './plugins/vite.electron.build'// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),vueJsx(),viteElectronDev(),viteElectronBuild()],base: './', //默认绝对路径改为相对路径 否则打包白屏resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}}
})

使用

启动:npm run dev
打包:npm run build

npm run dev启动后桌面出现应用界面,并自动打开开发者工具。修改 src 下的任何文件都会自动编译并重启应用
打包后启动可以添加 -m 全屏,-d 打开开发者工具

其他

  • https://xiaoman.blog.csdn.net/article/details/131713875?spm=1001.2014.3001.5502
  • https://www.electronjs.org/zh/docs/latest/tutorial/context-isolation
  • https://www.electronjs.org/zh/docs/latest/tutorial/ipc

相关文章:

vue vite ts electron ipc arm64

初始化 npm init vue # 全选 yes npm i # 进入项目目录后使用 npm install electron electron-builder -D npm install commander -D # 额外组件增加文件 新建 plugins 文件夹 src/background.ts 属于主进程 ipcMain.on、ipcMain.handle 都用于主进程监听 ipc&#xff0c;…...

数据分析-关于指标和指标体系

一、电商指标体系 二、指标体系的作用 三、统计学中基本的分析手段...

Vue+ElementUI操作确认框及提示框的使用

在进行数据增删改查操作中为保证用户的使用体验&#xff0c;通常需要显示相关操作的确认信息以及操作结果的通知信息。文章以数据的下载和删除提示为例进行了简要实现&#xff0c;点击下载以及删除按钮&#xff0c;会出现对相关信息的提示&#xff0c;操作结果如下所示。 点击…...

宋浩线性代数笔记(二)矩阵及其性质

更新线性代数第二章——矩阵&#xff0c;本章为线代学科最核心的一章&#xff0c;知识点多而杂碎&#xff0c;务必仔细学习。 重难点在于&#xff1a; 1.矩阵的乘法运算 2.逆矩阵、伴随矩阵的求解 3.矩阵的初等变换 4.矩阵的秩 &#xff08;去年写的字&#xff0c;属实有点ugl…...

Linux之Shell 编程详解(二)

第 9 章 正则表达式入门 正则表达式使用单个字符串来描述、匹配一系列符合某个语法规则的字符串。在很多文 本编辑器里&#xff0c;正则表达式通常被用来检索、替换那些符合某个模式的文本。在 Linux 中&#xff0c;grep&#xff0c; sed&#xff0c;awk 等文本处理工具都支持…...

TCP网络通信编程之字节流

目录 【TCP字节流编程】 // 网络编程中&#xff0c;一定是server端先运行 【案例1】 【思路分析】 【客户端代码】 【服务端代码】 【结果展示】 【案例2】 【题目描述】 【注意事项】 【服务端代码】 【客户端代码】 【代码结果】 【TCP字节流编程】 // 网络编程中&a…...

【暑期每日一练】 day8

目录 选择题 &#xff08;1&#xff09; 解析&#xff1a; &#xff08;2&#xff09; 解析&#xff1a; &#xff08;3&#xff09; 解析&#xff1a; &#xff08;4&#xff09; 解析&#xff1a; &#xff08;5&#xff09; 解析&#xff1a; 编程题 题一 描述…...

maven的基本学习

maven https://www.bilibili.com/video/BV14j411S76G?p1&vd_source5c648979fd92a0f7ba8de0cde4f02a6e 1.简介 1.1介绍 Maven翻译为"专家"、“内行”&#xff0c;是Apache下的一个纯Java开发的开源项目。基于项目对象模型(缩写:POM)概念&#xff0c;Maven利用一…...

疲劳驾驶检测和识别2:Pytorch实现疲劳驾驶检测和识别(含疲劳驾驶数据集和训练代码)

疲劳驾驶检测和识别2&#xff1a;Pytorch实现疲劳驾驶检测和识别(含疲劳驾驶数据集和训练代码) 目录 疲劳驾驶检测和识别2&#xff1a;Pytorch实现疲劳驾驶检测和识别(含疲劳驾驶数据集和训练代码) 1.疲劳驾驶检测和识别方法 2.疲劳驾驶数据集 &#xff08;1&#xff09;疲…...

安防监控视频汇聚EasyCVR修改录像计划等待时间较长,是什么原因?

安防监控视频EasyCVR视频融合汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、云存储、回放与检…...

EXCEL数据自动web网页查询----高效工作,做个监工

目的 自动将excel将数据填充到web网页&#xff0c;将反馈的数据粘贴到excel表 准备 24KB的鼠标连点器软件&#xff08;文末附链接&#xff09;、Excel 宏模块 优势 不需要编程、web验证、爬虫等风险提示。轻量、稳定、安全。 缺点 效率没那么快 演示 宏环境 ht…...

visual studio 2022换背景遇到的问题

如果要自定义背景图&#xff0c;则可以下载ClaudialIDE 1.在拓展->点击拓展管理->右上角搜索background->点击下载ClaudialIDE->加载完之后需要关闭vs界面进行下载&#xff0c;下载失败&#xff0c;弹出“由于出现以下错误 无法安装一个或多个扩展”。 解决&#x…...

MODBUS-TCP转Ethernet IP 网关连接空压机 配置案例

本案例是工业现场应用捷米特JM-EIP-TCP的Ethernet/IP转Modbus-TCP网关连接欧姆龙PLC与空压机的配置案例。使用设备&#xff1a;欧姆龙PLC&#xff0c;捷米特JM-EIP-TCP网关&#xff0c; ETHERNET/IP 的电气连接 ETHERNET/IP 采用标准的 T568B 接法&#xff0c;支持直连和交叉接…...

Go重写Redis中间件 - GO实现TCP服务器

GO实现TCP服务器 首先新建一个项目go-redis,将config和lib包放到项目中,config.go用来解析配置,比如端口、功能、DB数;lib包有两个文件夹,分别是logger和sync,其中logger.go是一个日志框架,sync包中的bool.go包装了atomic操作,因为atomic原生没有bool类型,所以将uint…...

使用Kmeans算法完成聚类任务

聚类任务 聚类任务是一种无监督学习任务&#xff0c;其目的是将一组数据点划分成若干个类别或簇&#xff0c;使得同一个簇内的数据点之间的相似度尽可能高&#xff0c;而不同簇之间的相似度尽可能低。聚类算法可以帮助我们发现数据中的内在结构和模式&#xff0c;发现异常点和离…...

内网穿透技术 - 带你玩转NATAPP

前言 使用内网穿透工具&#xff0c;我们就可以在公网中直接访问在局域网内搭建的服务器网页&#xff0c;也可以直接远程连接到局域网内的机器。本文章主要介绍下NATAPP内网穿透工具的使用。 NATAPP使用教程 官网 在官网先注册&#xff0c;然后登录。登录后&#xff0c;会有一…...

SQL server 简介

SQL server 简介 学习目的 SQL Server 是由微软公司开发的一种关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;用于存储和检索数据。它提供了一个可扩展的、安全的和可靠的数据存储和管理解决方案。 SQL Server 主要用于构建企业级应用程序&#xff0c;支持…...

springboot 之以enable开头的注解

Spring​ 有很多 Enable 开头的注解&#xff0c;平时在使用的时候也没有注意过为什么会有这些注解 Enable 注解 首先我们先看一下有哪些常用的 Enable 开头的注解&#xff0c;以及都是干什么用的。 EnableRetry​&#xff1a;开启Spring 的重试功能&#xff1b; EnableSch…...

#P1007. [NOIP2007提高组] 矩阵取数游戏

题目描述 帅帅经常跟同学玩一个矩阵取数游戏&#xff1a;对于一个给定的 n \times mnm 的矩阵&#xff0c;矩阵中的每个元素 a_{i,j}ai,j​ 均为非负整数。游戏规则如下&#xff1a; 每次取数时须从每行各取走一个元素&#xff0c;共 nn 个。经过 mm 次后取完矩阵内所有元素&…...

TypeScript基础篇 - TS模块

目录 模块的概念 Export 语法&#xff08;default&#xff09; Export 语法&#xff08;non-default&#xff09; import 别名 Type Export语法【TS】 模块相关配置项&#xff1a;module【tsconfig.json】 模块相关配置项&#xff1a;moduleResolution 小节总结 模块的…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...