b 32
,
r 104
,
❤ 正在询问中
序
-
虽然标题是
electron icp 封装(基于vue computed) , 但实际上这套封装可以应用到所有的前后端状态同步场景, 只需要修改一下事件监听与发送的代码。 -
代码中引入的其他函数的作用
env_isRenderer
:判断当前代码环境是否处于 renderer , 这个代码前后端都是可以引用的。useElectron
:获取Electron
对象useIpc
: 获取Electron.IpcRenderer
对象
-
这个封装的作用
- 无论是在主线程还是渲染线程对该函数产生的计算属性的
set value
都会通过 ipc 同步到主线程与所有的渲染线程 - 使用起来的时候就无需考虑
.on
这样的代码,就是简简单单的引入一个计算属性然后想咋用咋用。
- 无论是在主线程还是渲染线程对该函数产生的计算属性的
另外就没什么好说的了,直接去下面看源码吧,注释很详细。
源码
import { env_isRenderer } from "../sharedLib";
import { computed, ref, toRaw, UnwrapRef, WritableComputedRef } from "vue";
import { useElectron, useIpc } from "./electron";
export function useIpcComputed<T>(
channel: string,
defaultData: T
): WritableComputedRef<UnwrapRef<T>> {
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<T>) {
_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<T>) => (_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<string, any>();
export const getRendererUpdateChannel = (s: string) => `${s}-renderer-update`;
}
链接到此文档的相关文档
虽然标题是
by 崮生 from 崮生 • 一些随笔 🎨,欢迎 赞助本文
本文欢迎分享与聚合,全文转载未经授权( 联系我)不许可。