再electron中,进程间的通信通过ipcMain和ipcRenderer模块,这些通道是任意和双向的
ipc通道是通过预加载脚本绑定到window对象的electron对象属性上的
当用electron-vite脚手架搭建完项目之后在src文件夹下有三个文件夹
他们分别是:
//我们在这个中定义ipc的事件名称,翻遍后续的事件管理
export enum IpcEvents{
SAYHELLO="sayhello"
}
//引入相关的事件名称
import {ipcMain} from 'electron'
import {IpcEvents} from "../common/ipcEvents";
//ipc事件注册函数
const register=async ():Promise<void>=>{
ipcMain.on(IpcEvents.SAYHELLO,async (e)=>{
console.log('hello')
})
}
export default {register}
最后一步我们需要再main/index.ts主进程文件中注册ipc通道事件
//首先引入我们的ipc文件
import ipc from './ipc'
//然后我们找到这个函数
app.whenReady().then(async () => {
// Set app user model id for windows
...
...
await ipc.register() //需要注意的是我们要在这儿createWindwo()函数之前注册ipc事件(也就是在创建窗口之前注册)
createWindow()
...
...
})
在渲染进程中使用
<template>
<div class="home">
<n-button @click="clickHandler">点击</n-button>
</div>
</template>
<script lang="ts" setup>
import {IpcEvents} from "../../../../../common/ipcEvents";
//在此处点击事件
const clickHandler=()=>{
window.electron.ipcRenderer.send(IpcEvents.SAYHELLO) //此处调用事件
}
</script>
<style lang="scss" scoped>
.home{
height: 100%;
padding: 16px;
}
</style>
当我们点击后发现控制台出现相应的打印输出后表示注册成功
<template>
<div class="home">
<n-button @click="clickHandler">点击</n-button>
</div>
</template>
<script lang="ts" setup>
import {IpcEvents} from "../../../../../common/ipcEvents";
const datalist=[
{name:"yu",age:23,sex:"男"},
{name:"chao",age:23,sex:"女"},
{name:"zhi",age:23,sex:"未知"},
{name:"wang",age:24,sex:"男"},
]
const clickHandler=()=>{
const data=JSON.stringify(datalist)
window.electron.ipcRenderer.send(IpcEvents.SAYHELLO,data)
}
</script>
<style lang="scss" scoped>
.home{
height: 100%;
padding: 16px;
}
</style>
import {ipcMain} from 'electron'
import {IpcEvents} from "../common/ipcEvents";
const register=async ():Promise<void>=>{
ipcMain.on(IpcEvents.SAYHELLO,async (e,data)=>{
const dataList=JSON.parse(data)
console.log(dataList)
})
}
export default {register}
点击后会发现在控制台中中文会乱码
electron中中文乱码解决方案
在启动命令之前添加chcp 65001
解决electron控制台下打印中文乱码
"dev": "chcp 65001 && electron-vite dev",
?
现在我们重新启动项目,可以清除的看到中文不会乱码
我们首先在src/renderer/src下新建文件夹名hook
然后新建文件useIpcRendererOn.ts
import { onUnmounted } from 'vue'
//这儿要注意引入的ipc事件的地址,然后无脑粘贴
import { IpcEvents } from '../../../common/ipcEvents'
type IpcRendererListener = (event: any, ...args: any[]) => void
//用于监听主进程向渲染进行双向的通信
export default function useIpcRendererOn(
channel: IpcEvents,
listener: IpcRendererListener
): any {
const ipc = (window as any).electron.ipcRenderer
onUnmounted(() => {
ipc.removeListener(channel, listener)
})
return (window as any).electron.ipcRenderer.on(channel, listener)
}
重新定义新的事件名称
//我们在这个中定义ipc的事件名称,翻遍后续的事件管理
export enum IpcEvents{
SAYHELLO="sayhello",
SAYWORLD="sayworld"
}
住进程向渲染进程发送消息
import {ipcMain} from 'electron'
import {IpcEvents} from "../common/ipcEvents";
const register=async ():Promise<void>=>{
ipcMain.on(IpcEvents.SAYHELLO,async (e,data)=>{
const dataList=JSON.parse(data)
console.log(dataList)
const world=JSON.stringify([
{
name:"这个是主进程传递过来的",
value:1
}
])
//在这儿向渲染进程发送信息
e.sender.send(IpcEvents.SAYWORLD,world)
})
}
export default {register}
我们在渲染进程中来监听主程序的发送的数据
<template>
<div class="home">
<n-button @click="clickHandler">点击</n-button>
</div>
</template>
<script lang="ts" setup>
import {IpcEvents} from "../../../../../common/ipcEvents";
import useIpcRendererOn from "../../../hook/useIpcRendererOn";
const datalist=[
{name:"yu",age:23,sex:"男"},
{name:"chao",age:23,sex:"女"},
{name:"zhi",age:23,sex:"未知"},
{name:"wang",age:24,sex:"男"},
]
const clickHandler=()=>{
const data=JSON.stringify(datalist)
window.electron.ipcRenderer.send(IpcEvents.SAYHELLO,data)
}
//用来监听渲染进程发送的信息
useIpcRendererOn(IpcEvents.SAYWORLD,async (_,data)=>{
const list=JSON.parse(data)
console.log(list)
})
</script>
<style lang="scss" scoped>
.home{
height: 100%;
padding: 16px;
}
</style>
当我们点击按钮后回清晰看到在页面的开发者工具中打印出来主进程中传递过来的数据
上述行为整体剖析
由以上四步在住进程中形成了统一的闭环操作。
以上情况几乎能够完成所有的ipc通信操作,还有一种情况后续再说
首先在ipcEvents.ts中注册一个事件名称
export enum IpcEvents{
SAYHELLO="sayhello",
SAYWORLD="sayworld",
SAYTHANKYOU='Thankyou'
}
我们首先在渲染界面发送消息
<template>
<div class="home">
<n-button @click="clickHandler">点击</n-button>
<n-button @click="sayTankyouHandler">说谢谢</n-button>
</div>
</template>
<script lang="ts" setup>
import {IpcEvents} from "../../../../../common/ipcEvents";
import useIpcRendererOn from "../../../hook/useIpcRendererOn";
const datalist=[
{name:"yu",age:23,sex:"男"},
{name:"chao",age:23,sex:"女"},
{name:"zhi",age:23,sex:"未知"},
{name:"wang",age:24,sex:"男"},
]
const clickHandler=()=>{
const data=JSON.stringify(datalist)
window.electron.ipcRenderer.send(IpcEvents.SAYHELLO,data)
}
useIpcRendererOn(IpcEvents.SAYWORLD,async (_,data)=>{
const list=JSON.parse(data)
console.log(list)
})
const sayTankyouHandler=async ()=>{
//这儿发送消息,向主进程
await window.electron.ipcRenderer.invoke(IpcEvents.SAYTHANKYOU).then((data: string) => {
//data便是渲染进程中然会过来的数据
console.log(data)
})
}
</script>
<style lang="scss" scoped>
.home{
height: 100%;
padding: 16px;
}
</style>
住进程中接收并返回
import {ipcMain} from 'electron'
import {IpcEvents} from "../common/ipcEvents";
const register=async ():Promise<void>=>{
ipcMain.on(IpcEvents.EVPLAY,async (e,data)=>{
const dataList=JSON.parse(data)
console.log(dataList)
const world=JSON.stringify([
{
name:"这个是主进程传递过来的",
value:1
}
])
e.sender.send(IpcEvents.SAYWORLD,world)
})
//这个便是进行的双向通信说谢谢
ipcMain.handle(IpcEvents.SAYTHANKYOU,()=>{
return '谢谢'
})
}
export default {register}
我们可以看见非常的有礼貌,那你呢?
值得注意的是:
为了解决红色方框的第三个问题,以示诚意贴张图片
以上便是完整的ipc通信,说谢谢
?