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

超详细!!!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>

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

在这里插入图片描述


http://www.kler.cn/a/294605.html

相关文章:

  • Vue.js 项目创建流程
  • Centos安装Elasticsearch教程
  • OpenGL ES 共享上下文实现多线程渲染
  • 文件夹被占用了无法删除怎么办?强制粉碎文件夹你可以这样操作
  • NAT网络工作原理和NAT类型
  • java模拟键盘实现selenium上下左右键 table中的左右滚动条实现滚动
  • (1)DRF项目服务器部署(Linux/Nginx/Uwsgi)
  • 数据结构---双向链表(内存泄露相关知识)
  • 关于易优cms自定义字段不显示的问题
  • 梧桐数据库(WuTongDB):聚簇索引的原理、实现方法及应用场景
  • [RK3588][Android12] Android->拦截指定进程冻结,避免后台服务长时间运行被系统冻结
  • Spring全局异常处理HandlerExceptionResolver使用
  • 【网络安全基础】网络安全的基本概念与威胁
  • Python批量提取pdf标题-作者信息
  • Redis发布订阅PUB/SUB
  • 04使用python处理交通时空大数据
  • 初识Linux · 进度条
  • K8S 发布应用
  • 【60天备战软考高级系统架构设计师——第十一天:系统集成与测试——集成策略】
  • kafka集群安装
  • OpenFeign的使用(一)
  • 软件测试之UI自动化测试
  • nginx配置中的服务器名称
  • 家政上门小程序系统设计解析
  • C#语言实现最小二乘法算法
  • 怎么强制撤销excel工作表保护?