electron 多窗口的开发很费劲,如果你想让一份数据在不同的窗口中显示,并且实现数据修改后,ui 同步更改的功能,用 ipc 显然是费时费力的。网上关于两个窗口 ui 同步的文章也很少。
因为我工作中用的 react 和 mobx 较多,就想着一个 mobx 的 class 实例,能不能让两个窗口公用。
在 github mobx 仓库有一个 issue ,https://github.com/mobxjs/mobx/issues/1644
但是作者并没有给出实现,只是提到了因为不同窗口的 mobx 实例不同,所以做不到同步。
于是我想到能不能让其他的窗口(例如子窗口)使用来自于另一个窗口的 mobx
在窗口 A 中
import observer from 'mobx-react-lite';
import ReactDOM from 'react-dom';
window.observer = observer;
window.ReactDOM = ReactDOM;
window.store = store;
在窗口 B 中
const {observer, ReactDOM, store} = windowA;
const Component = observer(()=>{
return <div>{store.something}</div>;
});
ReactDOM.render(<Component/>, container);
这样便可以用同一份数据,实现两个窗口的 ui 同步。
效果图:
1
zsj1029 2023-03-08 13:26:07 +08:00
Nice 非常好的思路,原理是什么呢,两个窗口两个实例独立内存运行时
window 对象支持相互引用吗 |
2
travisyang OP @zsj1029 虽然是两个独立内存,但是通过 window 对象,两者可以拿到互相的内容。
window 对象支持互相引用,通过 window.open 函数的返回值可以拿到窗口对象的引用,也可以通过 window.opener 得到打开窗口的那个窗口 const childWindow = window.open(); const parentWindow = window.opener; 因此我尝试用同一个 ReactDOM 引用去渲染不同窗口的视图,发现真的可以实现同步。 |
3
lizhenda 2023-03-08 14:33:53 +08:00
window.open 打开的子窗口才可以这么玩的吧,这个 windows 是对象是 electron 帮你在创建窗口时传递的。如果是主进程创建的其它不相关的窗口,那就没办法了。适用性偏低。不如自己把 ipc 和 proxy 封装下。状态管理本质就是 proxy 调用 ipc 去更新而已。
|
4
travisyang OP @lizhenda 好的,我突然发现我这种方式在子窗口的组件中不能用 react hook 了,感觉确实有局限性。
|
5
travisyang OP @lizhenda 其实我觉得最简单的还是主窗口用 BrowserWindow 创建,其他窗口通过主窗口的渲染进程打开,将 mobx store 对象暴露在 window 上,然后修改互相的 window.store 的属性值,就能实现视图同步。但这样的问题在于多个窗口就要有多个 store 对象,而不是一个 store 对象可以被多个窗口监听到。我本来想表达这个主题,刚刚发现这种局限性很大😢
|