超详细!!!electron-vite-vue开发桌面应用之创建新窗口以及主进程和子进程的通信监听(十二)

云风网
云风笔记
云风知识库

一、新建打开窗口

1、在electron/main.ts中加入主进程打开窗口逻辑代码
import { ipcMain } from "electron";
ipcMain.handle("open-win", (_, arg) => {
  const childWindow = new BrowserWindow({
    webPreferences: {
      preload:path.join(__dirname, 'preload.mjs'),
      nodeIntegration: true,
      contextIsolation: false,
    },
  });
  childWindow.loadFile(path.join(RENDERER_DIST, 'index.html'),{
    hash: arg
  });
});
2、在electron/preload.ts中定义ipcRenderer全局方法
import { ipcRenderer } from 'electron'
window.ipcRenderer = ipcRenderer
3、在src/utils下新建electron.ts封装打开窗口的公共方法
/**
 * 新建窗口
 * @param path 路由地址
 */
export function openWindow(path: string) {
  window.ipcRenderer.invoke("open-win", path);
}
export default {
  openWindow
};
4、在前端文件中应用打开新的窗口
<script setup lang="ts">
const router = useRouter()
import electronUtils from "@/utils/electron";
const toUser = () => {
  router.push('/userManage')
}
const toNote = () => {
  router.push('/func/noteManage')
}
const toLogin = () => {
  router.push('/login')
}
const toOpenLogin = () => {
  electronUtils.openWindow('/login');
}
</script>

<template>
  <div class="container">
    <a @click="toUser()">用户管理</a>
    <a @click="toNote()">语录管理</a>
    <a @click="toLogin()">去登录</a>
    <a @click="toOpenLogin()">创建新窗口</a>
  </div>
</template>

在这里插入图片描述
在这里插入图片描述

二、主进程和子进程的通信

electron项目常常由一个主进程和多个渲染进程构成,渲染进程之间是隔离的,而所有渲染进程都和主进程共享资源。

  1. 所有的渲染进程都是由主进程创建的
  2. 每个窗口都对应着一个渲染进程
  3. 所有的渲染进程共享一个主进程
  4. 渲染进程与渲染进程交互【多窗口交互】,都需要借助ipc通信来实现

2.1、子进程向主进程单向通信

1、在electron目录下创建ipc.ts
import { ipcMain } from "electron";

export const initIpc = () => {
  // 同步通信监听
  ipcMain.on("eventSync", (e, data: string) => {
    setTimeout(() => {
      e.returnValue = "主进程同步响应:" + data;
    }, 1000);
  });

  // 异步通信监听
  ipcMain.handle("eventAsync", (e, data: string) => {
      return "主进程异步响应:" + data;
  });

  // 异步通信一次
  ipcMain.handleOnce("eventAsyncOnce", (e) => {
    console.log("异步通信一次!",e);
  });
};
2、在main.ts引入初始化
import {initIpc} from './ipc'
//初始化initIpc
initIpc()
3、在用户管理新增用户详情编辑子路由
{
    path: '/',
    component: Layout,
    hidden: false,
    redirect: 'noredirect',
    children: [
      ...
      {
        path: 'userManage/detail',
        component: () => import('@/views/userManage/detail.vue'),
        name: 'detail',
        meta: { title: '用户详情', icon: 'user' },
        hidden: true
      }
    ]
  }
4、在src/views/userManage下新建detail.vue
<script setup lang="ts">
import { ipcRenderer } from "electron";

function toSyncSaveUserInfo() {
  const result = ipcRenderer.sendSync("eventSync", "同步保存");// 同步通信测试
  console.log(result);
}
function toAsyncSaveUserInfo() {
  const result = ipcRenderer.invoke("eventAsync", "异步保存");// 异步通信测试
  console.log(result);
}
function toAsyncOnceSaveUserInfo() {
  const result = ipcRenderer.invoke("eventAsyncOnce", "异步保存一次");// 异步通信测试一次
  console.log(result);
}
</script>

<template>
  <a @click="toSyncSaveUserInfo()">同步保存</a>
  <a @click="toAsyncSaveUserInfo()">异步保存</a>
  <a @click="toAsyncOnceSaveUserInfo()">异步保存一次</a>
</template>

<style scoped>

</style>
4、在src/views/userManage/index.vue添加打开编辑用户信息窗口的代码
<script setup lang="ts">
import electronUtils from "@/utils/electron";
const router = useRouter()
const toIndex = () => {
  router.push('/')
}
const toNote = () => {
  router.push('/func/noteManage')
}
const toEditUserInfo = () => {
  electronUtils.openWindow('/userManage/detail');
}
</script>

<template>
  <a @click="toIndex()">首页</a>
  <a @click="toNote()">语录管理</a>
  <a @click="toEditUserInfo()">编辑用户详情</a>
</template>

<style scoped>

</style>

在这里插入图片描述

5、点击打开用户详情子窗口进程

在这里插入图片描述

点击保存用户信息,子进程向主进程通信

同步保存、异步保存、异步保存一次,其中异步保存一次后主进程移除监听,再次点击保存报错

2.2、主进程向子进程单向通信

1、main.ts定义定时器通信数据给子进程
ipcMain.handle("open-win", (_, arg) => {
  const childWindow = new BrowserWindow({
    webPreferences: {
      preload:path.join(__dirname, 'preload.mjs'),
      nodeIntegration: true,
      contextIsolation: false,
    },
  });
  let count = 100
  setInterval(() => {
    if (childWindow&&childWindow.webContents) {
      childWindow?.webContents.send("to-child-count", '金额:'+count++);
    }
  }, 1000);
  childWindow.webContents.openDevTools();
  childWindow.loadFile(path.join(RENDERER_DIST, 'index.html'),{
    hash: arg
  });
  
});
2、detail.vue监听主进程通信数据
// 监听主进程信息
function toChildCount(e:any,data:string){
    console.log(data)
}
onMounted(()=>{
    ipcRenderer.on("to-child-count",toChildCount);
    console.log("监听主进程信息")
});
onUnmounted(()=>{
    console.log('移除监听主进程信息')
    ipcRenderer.removeListener("to-child-count",toChildCount);
});

在这里插入图片描述

2.3、主进程和子进程双向通信

1、electron/ipc.ts添加双向通信逻辑
//双向通信
ipcMain.handle("eventBothWay", (e, data: string) => {
  e.sender.send("eventBothWay", "主进程发送" + data);
});
2、detail.vue子进程添加监听逻辑
function eventBothWay(e:any,data:string){
    console.log("子进程监听的信息:",data);
}
function toBothWay(){
  ipcRenderer.invoke("eventBothWay","异步发给主进程的消息");
}
onMounted(()=>{
    ipcRenderer.on("eventBothWay",eventBothWay);
    
    // ipcRenderer.on("to-child-count",toChildCount);
    // console.log("监听主进程信息")
});
onUnmounted(()=>{
    ipcRenderer.removeListener("eventBothWay",eventBothWay);

    // console.log('移除监听主进程信息')
    // ipcRenderer.removeListener("to-child-count",toChildCount);
});
<a @click="toBothWay()">双向通信</a>

点击双向通信,可以控制台获取双向信息打印

在这里插入图片描述

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值