使用vue開發桌面應用(electron)

零基礎使用electron編寫記錄/複習單詞的軟件vocabook. 記錄了第一次開發electron遇到的問題與如何組合使用api來實現一般的需求.css

這個項目是使用了electron-vue做爲模板的.
使用起來很是簡便, 只要:html

// 若是沒有vue-cli須要先安裝
npm i -g vue-cli
vue init simulatedgreg/electron-vue my-project

走到這裏已經有用vue寫的跨桌面應用的全部東西了. 若是未了解electron能夠移步這裏來了解vue

這個系列把問題做爲標題, 實現過程做爲內容node

如何控制每一個窗口的控制條與標題欄

electron默認的窗口是顯示在正中, 帶有標題欄, 能夠拖動大小的窗口. 然而在各個不一樣場景, 咱們須要不一樣的窗口, 接下來講一下不一樣形態的窗口的配置.ios

建立窗口使用了main process中的BrowserWindow對象, 在文檔無邊框窗口的文檔裏介紹了這個部分提到的全部配置和更多的配置.git

主窗口

主窗口的需求是不要標題欄, 這樣能夠自定義ui, 不讓標題欄影響界面, 配置爲titleBarStyle: 'hidden'. 如此產生了一個問題, 沒有標題欄不能拖動. 結局方案是在dom上加上-webkit-app-region: drag;-webkit-user-select: none;的css就可使dom變得能夠拖動窗口. 另外主窗口的設計是有最小寬度和最小高度. 那麼就是用minHeightminWidth來設置.github

配置窗口

這個項目會有"配置"的功能, 那麼配置的窗口通常是寫死大小, 不能拖動的. 也不能最大化和最小化.web

{
  titleBarStyle: 'customButtonsOnHover',
  resizable: false,
  minimizable: false,
  maximizable: false
}

迷你面板

迷你面板是主界面的第二形態, 指望的行爲是置頂窗口, 並自定義窗口控制(紅綠燈). 那麼配置爲:vuex

{
  alwaysOnTop: true,
  frame: false
}

其中alwaysOnTop是置頂窗口, 迷你面板會覆蓋其餘全部程序, frame是去除窗口控制按鈕(最大化/最小化/關閉)chrome

優雅顯示窗口

由於頁面加載須要時間, 而打開窗口之後還在加載頁面會使體驗變差, 能夠把初始窗口配置的show字段設爲false, 並監聽加載事件操做窗口:

mainWindow.once('ready-to-show', () => {
    mainWindow.show()
  })

http請求跨域

在這個項目中使用了axios做爲http庫, 但由於跨域問題研究了一天, 解決方法很簡單. 和chrome插件相似, 配置窗口的安全策略.

webPreferences: {
  webSecurity: false
}

配置窗口的顯示

爲配置窗口新增了一個一級路由, 可是在build環境下和dev環境下url不一樣, dev爲http協議, build爲file協議, baseurl的寫法:

const winURL = process.env.NODE_ENV === 'development'
  ? `http://localhost:9080`
  : `file://${__dirname}/index.html`

配置窗口與主窗口的數據

配置窗口是一個獨立的頁面, 與主窗口是分離的, 那麼如何在配置窗口切換了設置之後讓主窗口感應到成了一個問題.

這裏用到了:

  • ipc傳遞事件
  • vuex插件
  • main process webContents獲取全部窗口

流程:

  1. 經過vuex插件來像main process發送事件, 並在vuex插件中監聽消息, 直接commit來改變vuex的state
  2. 在main process中監聽事件, 由於事件參數只能得到來源窗口, 因此須要調用webContents.getAllWebContents()來獲取全部窗口, 向別的窗口發送設置變化的事件.

具體代碼:

vuex plugin:

const {ipcRenderer} = require('electron')

export default store => {
  store.subscribe((mutation, state) => {
    if (mutation.type === 'ipc/theme') {
      ipcRenderer.send('themeChange', state.config.theme)
    }
  })
  ipcRenderer.on('broadcastTheme', (event, arg) => {
    store.commit('config/setTheme', arg)
  })
}

main process:

ipcMain.on('themeChange', (event, arg) => {
  webContents.getAllWebContents().forEach(v => {
    v.send('broadcastTheme', arg)
  })
})

如何切換主窗口與迷你面板

切換窗口也是經過了ipc事件來作的, 須要在主進程保存當前打開的窗口的變量, 來決定關閉了窗口以後再次激活應用打開的是主窗口仍是迷你面板.

如何存儲數據

我用了nedb來儲存數據, 使用main process的apiapp, app.getPath('userData')能夠獲取用戶存儲數據的路徑來鏈接數據庫.

nedb介紹

nedb是個模仿mongoodb查詢方式的node數據庫, 在electron項目裏把實例建立在文件上就好了, 介紹一些概念:

  • collection 對應 數據庫的表, 一個collection爲一個實例(一個文件)
  • document 對應 數據庫的列

原文地址

相關文章
相關標籤/搜索