当前位置: 首页 > Web前端 > HTML5

开发了一个写作软件(OSX,Windows),带着一个Electron开发指南

时间:2023-04-05 21:59:21 HTML5

断断续续写了一个月,昨天终于完成了第一个版本...碧落写作帮助网络作家更方便的创作小说PC软件目前支持OSX/Windows。这个名字的灵感来自杜甫的一首诗。前两句是:《寄李十二白二十韵》从前有狂人,名尔逐仙。笔落风雨惊,诗成泣鬼神。至于名字,感谢@蓝色首页,大家可以去官网看看。作为我的第一个商业产品(虽然只卖了一个,但还是朋友的支持。。。)产品,我投入了很多精力。而且,重要的还在后面,那就是运营。如何让更多人知道并使用它?直觉告诉我,这会比写代码更难。。。Electron开发(cai)分发(keng)指南主要使用Electron-Vue框架,让我不用再花时间思考配置Webpack和Electron.上来直接开发就行了。感谢开源社区!歪楼:我对Wepback的看法是,对运行原理有一个大概的了解就可以了。可以直接使用现成配置好的Webpack模板。遇到特殊需求的时候,查文档和谷歌就知道怎么改了。开发需要你熟悉Vue和Node。我不会在这里谈论基础知识。除了官方文档,网上还有更多相关文章可供选择。细数一下我踩过的坑:首先遇到:dev模式没问题,但是打包后出现空白页的问题?如果你只是生成工程,没有动任何东西,可能是Webpack把Vue当成一个外部文件,没有打包进去。代码在:webpack.renderer.config.js注释掉...Object.keys(dependencies||{}).filter(d=>!whiteListedModules.includes(d))然后,我遇到了多窗口的需求:一开始我没有想法,因为一般前端遇到多窗口和多路由-端开发,多Tab不是一回事。经过别人指点,才知道多窗口其实很简单。//主窗口变量constwinURL=process.env.NODE_ENV==='development'?`http://localhost:9080`:`file://${__dirname}/index.html`//设置URL或文件,毕竟ElectronApp实际运行在Chromium中mainWindow=newBrowserWindow(options)//new一个window对象,同时传递一些参数mainWindow.loadURL(winURL)//加载URL,加载完成后显示窗口。那么,我们照例,第二个窗口可以这样写letsecondWindow;constmodalPath=process.env.NODE_ENV==='开发'?'http://localhost:9080/#/showOutline':`file://${__dirname}/index.html#showOutline`//真的很简单...secondWindow=newBrowserWindow(options)secondWindow.loadURL(modalPath)PS:这里提醒一下,不要把vue-router设置成history模式。原因在文档里看过,忘了,想知道的再去查文档:pvuexexceptionundermulti-window:Ididn'trealizedthevuexwasaproblemwhendevelopingmulti-窗户。后来发现数据不匹配,再查问题时发现两个窗口的状态(state)不同步,即:当你打开窗口B时,两个窗口的Vuex数据是这时候是一致的,但是一旦你的窗口B的数据状态发生了变化,它就无法在窗口A中体现出来。为什么不呢,其实还是很好理解的。歪楼:说说我对Vuex实现原理的理解。在学习Vuex之前刚开始学习Vue时,我解决了多个组件(非父子)之间的通信方式,除了使用父组件作为中间人(事件总线)外,我还尝试维护一个全局的JSON(比如共享一个store.js),其他组件就可以访问和操作了。后来学习了Vuex,发现和我想的一样。(当然我没看源码,它真正的实现方法是什么。但是我的直觉告诉我应该是对的!)请教一个问题:为什么两个窗口之间的数据可以全部同步时间?解决方案:我结合了Electron文档中提到的两种方式:ipc通信和在主进程维护全局变量。没听说过。。。)Vue实现富文本编辑器:输入框和自动对焦(autofocus)的双向绑定不是Electron的问题,只能说是Vue的问题。当初写这个项目的时候,并没有打算自己实现一个富文本编辑器。本着使用开源的原则,我测试了项目中的一些开源编辑器,发现或多或少都存在问题。我后来想了想,反正这个项目的富文本编辑器需求并不复杂,自己实现一个就好了。对于编辑器的输入框,我使用HTML属性contenteditable来实现。关于编辑器组件的双向绑定和自动聚焦的详细介绍,请参考这篇文章。另外,还有一些不知道为什么的坑:我使用lowdb来本地存储用户数据:本质是通过node的fs模块来操作本地的json文件,但是比我们自己的实现更加优雅可靠.然后有一个需求,当触发某个条件时,保存对应的变量://当用户点击Button时Adb.set('a',111)。write();//当用户点击Button时Bdb.set('b',222).write();这时如果用户点击ButtonA,不仅a数据会更新,b数据也会更新,反之亦然。这不是lowdb问题,因为我单独测试过,点击ButtonA不会引起其他set函数调用!所以这应该是一个奇怪的问题。使用ipcRenderer监听通信时,如果监听器中使用了异步:ipcRenderer.on('delete',()=>{//这里的异步特指setTimeoutsetTimeout(()=>{//something,_this.remove会调用多次(但是发现ipcMian.send只调用了一次!)_this.remove(this.nodeWasRightClicked,this.dataWasRightClicked);},0);});另外:我在打包软件的时候也遇到了很多问题,不过最终都被谷歌解决了,这里就不再赘述了(所谓为谷歌编程)。其他问题后续会陆续补充,欢迎继续关注!