開發了一款寫做軟件(OSX,Windows),附帶Electron開發指南

斷斷續續寫了個把月,終於在昨天完成了初版…

筆落寫做


一款幫助網絡寫手更方便地進行小說創做的PC軟件,目前支持 OSX/Windowsjavascript

名字靈感來自於杜甫的一首詩,前兩句是:html

《寄李十二白二十韻》

昔年有狂客,號爾謫仙人。前端

筆落驚風雨,詩成泣鬼神。vue

對於名字,要感謝下@藍色java

預覽的話,能夠去官網node

做爲個人第一款商業性(雖然才賣出去一個,仍是朋友捧場…)產品,我投入了不少精力。並且,重要的還在後面,那就是運營webpack

怎麼讓得讓更多的人知道而且去使用它?直覺告訴我,這將是比寫代碼還要難的事情...git

Electron 開(cai)發(keng)指南


主要用到了Electron-Vue這個框架,讓我不用花時間去琢磨配置WebpackElectron,上來就直接開發。感謝開源社區!github

歪個樓:我對Wepback的見解就是,籠統的瞭解下運行原理就好了,現成而且配置好的Webpack模板直接用,遇到特殊需求,查文檔,查Google知道怎麼改便可。

開發要求你比較熟悉VueNode,這裏不會講基礎的東西,講基礎知識的除了官方文檔,網上有更多相關文章可供選擇。web

細數踩過的坑:

首先,我遇到了:dev模式沒問題,打包後空白頁的問題?

若是你剛剛生成項目,什麼都沒有動的話,那就多是Webpack在打包時,把Vue當成了外部文件沒有打包進去。

代碼在:webpack.renderer.config.js

註釋掉...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d))便可

而後,又遇到了多窗口的需求:

開始沒思路,由於多窗口和通常前端開發時遇到的多路由,多Tab還不是一回事兒。後來經人指點,才明白其實多窗口挺簡單的...

咱們先觀察生成的代碼模板中,主窗口是怎麼生成的:

let mainWindow;  //主窗口變量
const winURL =    
  process.env.NODE_ENV === 'development' ?
  `http://localhost:9080` :
  `file://${__dirname}/index.html`  // 設置URL或者文件,畢竟Electron App其實運行在Chromium中
  
mainWindow = new BrowserWindow(options)  // new 一個窗體對象,同時傳一些參數
mainWindow.loadURL(winURL)    // 加載URL,加載以後,窗口就會被顯示出來。

那麼,咱們依葫蘆畫瓢,第二個窗口就能夠這麼寫

let secondWindow; 
 const modalPath = process.env.NODE_ENV === 'development' ?
    'http://localhost:9080/#/showOutline' :
    `file://${__dirname}/index.html#showOutline`  // 的確比較簡單...
  
secondWindow = new BrowserWindow(options)  
secondWindow.loadURL(modalPath)

PS: 這裏提醒下vue-router不要設置成history模式。緣由在文檔裏看到過,忘了,想知道就去查文檔 :p

多窗口下的Vuex異常:

開發多窗口時並無意識到vuex存在問題,後面發現數據怎麼都對不上,而後排查問題時發現,兩個窗口的state(狀態)並不一樣步,即:

當你在打開窗口B時,此時兩個窗口的Vuex數據時一致的,但一旦你的B窗口的數據狀態發生變化,其並不能反映到窗口A裏。爲何不行,其實也很好理解。

歪個樓:說下我對Vuex實現原理的理解。之前剛開始學習Vue尚未學Vuex時,當時我解決多組件(非父子)之間的通信方式除了利用父組件作中間人(event bus)外,還試過維護一個全局JSON(好比共用一個store.js),而後其餘組件都能訪問及操做。後來學了Vuex,發現它的工做方式和我想的差很少。(固然,我並無去看源碼,它真正的實現方式是什麼。但直覺告訴我應該是這樣沒錯了!)

讓我反問一句:爲何兩個窗口之間的數據能一直同步?

解決方法: 我結合了Electron文檔中提到的兩種方式:ipc通信在主進程維護全局變量

PS: 經人點撥,ipc通信的實現利用了瀏覽器的postMessage接口(話說這個API,以前還真沒聽過說...)

在Vue中本身實現富文本編輯器:輸入框的雙向綁定和自動聚焦(auto focus)

還有個不算是Electron,只能說是Vue方面的問題。

原本寫這個項目時就沒打算來本身實現富文本編輯器,本着能用開源就用開源的原則,在項目裏測試了一些開源的編輯器,發現或多或少都有些問題,後來一琢磨,反正這個項目的富文本編輯器需求不復雜,就本身實現一個好了。

編輯器的輸入框,我使用的HTML屬性contenteditable來實現。

編輯器組件的雙向綁定和自動聚焦的細節參考這篇文章

此外,還有些坑不知道什麼緣由形成的:


用戶數據的本地存儲我用了lowdb

本質就是經過 nodefs模塊來操做本地 JSON文件,只不過它比咱們本身實現的要優雅,可靠多了

而後有個需求是,當觸發某種條件時,保存對應的變量:

// 當用戶點擊Button A
db.set('a',111).write();
// 當用戶點擊Button B
db.set('b',222).write();

此時,若是用戶點擊了Button A,不只a 數據會更新,b數據也會更新,反之一樣。

這不是lowdb的問題,由於我單獨測試過,點擊Button A並不會致使其餘set函數調用!

因此這應該算是一個奇怪的問題吧。

利用ipcRenderer監聽通訊時,若是在listener內使用了異步:

ipcRenderer.on('delete', () => {
     // 異步這裏特指setTimeout
     setTimeout(() => {
     // 不知爲什麼,_this.remove會調用屢次(但發現ipcMian.send只被調用了一次!)
     _this.remove(this.nodeWasRightClicked, this.dataWasRightClicked);
     }, 0);
 });

另外: 打包軟件時也遇到了不少問題,但最終都經過Google解決掉了,因此這裏不復述了(所謂面向Google編程

其餘問題後續會繼續補充,歡迎持續關注!
相關文章
相關標籤/搜索