electron icp 封装(基于vue computed)

点击这里直接去看源码 >>>
虽然标题是 electron icp 封装(基于vue computed), 但实际上这套封装可以应用到所有的前后端状态同步场景, 只需要修改一下事件监听与发送的代码。
代码中引入的其他函数的作用
env_isRenderer :判断当前代码环境是否处于 renderer , 这个代码前后端都是可以引用的。
useElectron :获取 Electron 对象
useIpc : 获取 Electron.IpcRenderer 对象
这个封装的作用
无论是在主线程还是渲染线程对该函数产生的计算属性的 set value 都会通过 ipc 同步到主线程与所有的渲染线程
使用起来的时候就无需考虑 .on 这样的代码,就是简简单单的引入一个计算属性然后想咋用咋用。
另外就没什么好说的了,直接去下面看源码吧,注释很详细。

源码

起源项目
ts
import { env_isRenderer } from "../sharedLib"; import { computed, ref, toRaw, UnwrapRef, WritableComputedRef } from "vue"; import { useElectron, useIpc } from "./electron"; export function useIpcComputed( channel: string, defaultData: T ): WritableComputedRef> { const { cacheMap, getRendererUpdateChannel } = useIpcComputed; if (cacheMap.has(channel)) { return cacheMap.get(channel); } else { const _ref = ref(defaultData); const _computed = computed({ get() { return _ref.value; }, set(v: UnwrapRef) { _ref.value = v; if (env_isRenderer()) { // 客户端更新值到服务端,这里会使发送者的 computed 触发两次更新(它自己 set 一次,这里一次), // 不过这不是什么大问题,还可以保持各端的数据一致 useIpc().send(getRendererUpdateChannel(channel), v); } else { // 服务端推送新值到所有客户端 useElectron() .webContents.getAllWebContents() .forEach((webContent) => webContent.send(channel, v)); } }, }); if (env_isRenderer()) { // 客户端第一次调用 useIpcComputed 从 主线程 更新一下默认值 useIpc().send(channel); // 客户端监听服务端的值更新 useIpc().on(channel, (event, v: UnwrapRef) => (_ref.value = v)); } else { // 客户端第一次调用 useIpcComputed 会从 主线程 更新一下默认值,这里用于处理该事件 useElectron().ipcMain.on(channel, (event, v) => { // 因为 ref.value 是一个 proxy 而 event.reply 内部无法序列化 proxy const _raw_v = toRaw(_ref.value); event.reply(channel, _raw_v); }); // 客户端主动更新值 useElectron().ipcMain.on( getRendererUpdateChannel(channel), (event, v) => { _computed.value = v; } ); } cacheMap.set(channel, _computed); return _computed; } } export namespace useIpcComputed { export const cacheMap = new Map(); export const getRendererUpdateChannel = (s: string) => `${s}-renderer-update`; }