不使用 ipc 实现 electron 多窗口 ui state 同步更新的一种方法 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
travisyang
V2EX    程序员

不使用 ipc 实现 electron 多窗口 ui state 同步更新的一种方法

  •  
  •   travisyang
    wxydev1 2023-03-07 23:09:04 +08:00 2087 次点击
    这是一个创建于 1013 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 同步。

    效果图:

    效果图

    demo 链接: https://github.com/wxydev1/electron-sync-state

    5 条回复    2023-03-08 15:33:52 +08:00
    zsj1029
        1
    zsj1029  
       2023-03-08 13:26:07 +08:00
    Nice 非常好的思路,原理是什么呢,两个窗口两个实例独立内存运行时
    window 对象支持相互引用吗
    travisyang
        2
    travisyang  
    OP
       2023-03-08 14:24:09 +08:00
    @zsj1029 虽然是两个独立内存,但是通过 window 对象,两者可以拿到互相的内容。

    window 对象支持互相引用,通过 window.open 函数的返回值可以拿到窗口对象的引用,也可以通过 window.opener 得到打开窗口的那个窗口

    const childWindow = window.open();

    const parentWindow = window.opener;

    因此我尝试用同一个 ReactDOM 引用去渲染不同窗口的视图,发现真的可以实现同步。
    lizhenda
        3
    lizhenda  
       2023-03-08 14:33:53 +08:00
    window.open 打开的子窗口才可以这么玩的吧,这个 windows 是对象是 electron 帮你在创建窗口时传递的。如果是主进程创建的其它不相关的窗口,那就没办法了。适用性偏低。不如自己把 ipc 和 proxy 封装下。状态管理本质就是 proxy 调用 ipc 去更新而已。
    travisyang
        4
    travisyang  
    OP
       2023-03-08 14:56:21 +08:00
    @lizhenda 好的,我突然发现我这种方式在子窗口的组件中不能用 react hook 了,感觉确实有局限性。
    travisyang
        5
    travisyang  
    OP
       2023-03-08 15:33:52 +08:00
    @lizhenda 其实我觉得最简单的还是主窗口用 BrowserWindow 创建,其他窗口通过主窗口的渲染进程打开,将 mobx store 对象暴露在 window 上,然后修改互相的 window.store 的属性值,就能实现视图同步。但这样的问题在于多个窗口就要有多个 store 对象,而不是一个 store 对象可以被多个窗口监听到。我本来想表达这个主题,刚刚发现这种局限性很大
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2869 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 14:05 PVG 22:05 LAX 06:05 JFK 09:05
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86