使用 Electron 開發一款理財計算器

BonnieReard 8年前發布 | 72K 次閱讀 Electron 前端技術

Electron 是一個跨平臺應用框架,原本為 Atom 設計,后來單獨分離了出來。它提供了一些與原生系統交互的 API ,可以方便快速使用 HTML、JavaScript、CSS 等 Web 技術開發跨平臺應用。

最近基于 Electron 開發了一個簡單的 理財計算器 。發布了 1.0 版本之后,總結一下這段時間的開發經歷。哦對了,價格是隨便定的,主要是熟悉下流程,大家千萬別買。

這篇文章只包含個人開發小結,不包括各種框架工具的基礎使用,如有需要請自行 Google 。

過程

理財計算器的功能很簡單,目前只做了股票的保本賣出價的計算。

輸入買入價、買入數量等信息,算上各種手續費之后,輸出保本賣出的價格。

看起來很簡單的功能,大概卻做了5天,主要在開發環境配置上卡了挺久。

基礎項目

一開始需要做的是搭建整個項目的基礎框架,主要包含以下幾個方面:

  • electron :跨平臺框架,主要是封裝 Web 應用,并且打包發布。
  • webpack :模塊加載打包工具,可以通過各種 loader 加載不同資源。
  • eslint :JS 代碼靜態檢測工具,可以方便的統一代碼的風格。
  • babel :可以將 ES6 代碼轉為 ES5 代碼的語法編譯器。
  • vue :前端框架,數據驅動的組件化開發,配上 vue-loader 之后十分好用。

上面這一套東西要搞一下還是比較費時間的,好在網上有各種現成的模板,貨比三家之后最后選用了 electron-boilerplate-vue ,搭建好后文件目錄如下:

.
├── .babelrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── README.md
├── app
│   ├── ...
│   ├── main.html
│   ├── main.js
│   └── package.json
├── build
│   ├── ...
│   ├── webpack.base.conf.js
│   ├── webpack.dev-background.conf.js
│   ├── webpack.dev-server.conf.js
│   └── webpack.pro-build.conf.js
├── config.js
├── package.json
└── test

前端頁面

接下來就是前端頁面部分。一直想試試 Material Design 風格,剛好這次是個不錯的機會,于是就開始找找有沒有 MD 方面的前端庫。

先是想看看有沒有類似于 Ant Design 這樣的成套 vue 組件庫,于是找到了 material-ui ,可惜是 React 版本的。找找了 vue 版本的似乎只有 vue-mdlvue-material 這兩個不太成氣候的庫,仔細想想本身它們都依賴于其他前端庫和 vue ,萬一更新不及時豈不是很坑爹。于是棄了這個想法。

后來就是去找類似于 semantic-uiFoundation 這樣純粹的前端庫,找到 materializecss 這個庫,頁面簡潔大方,破兒費(Perfect)啊!

然后,就是為期兩天的填坑之旅。

是的,一共5天的開發時間,調教這個前端庫花了2天,而且坑爹的是,最后還沒用上。主要問題在于它的 JS 代碼是基于 jQuery 的,而很多插件又是在 $(document).ready 里加載的,對 SPA 非常不友好,因為 document ready 的時候我的 dom 們還沒 ready 。再加上我對 Webpack 又不是很熟悉,導致點擊事件不響應,不知道是 webpack 打包的問題還是 vue-loader 加載順序的問題還是 babel-loader 編譯的問題還是它自己庫的問題還是 jquery 引入的問題。

總之就是,一套系統過于龐大,雖然腳手架讓我避開了大量的體力勞動,但是同時也引入了很多我不熟悉的未知因素。于是就剛好花兩天時間,仔細學習了項目中用到的各種技術和工具。熟悉了之后才發現我以前多慮了,問題肯定出在源碼上。然后就找到了問題的原因。

最后決定放棄 materializecss 這個庫,然后去試了試 Google 家的 Material Design Lite

萬萬沒想到,5分鐘解決戰斗。

引入 CSS 的方法和 materializecss 類似,都是在 SCSS 里 import 它的原文件:

/* IMPORT VARIABLES */
@import 'material-design-lite/src/_variables.scss';
/* OVERRIDE VARIABLES */
$layout-screen-size-threshold: 0px;
/* IMPORT MDL */
@import 'material-design-lite/src/material-design-lite.scss';

引入 JS 文件的方法也很簡單,和其他庫一樣 import 就行:

import 'material-design-lite'

不過和 materializecss 不同的是,文檔里在 《 Use MDL on dynamic websites 》 寫清楚了動態更新頁面后的更新方法:

// upgrade element
componentHandler.upgradeElement(button)
// upgrade dom
componentHandler.upgradeDom()

于是在 vue 的項目里,只要這么寫就可以了:

<template>
 ..
</template>

<script type="text/babel"> 
 export default {
 ready: () => {
 componentHandler.upgradeDom()
 },
 components: {
 ...
 },
 }
</script>

<style lang="scss" rel="stylesheet/scss"> 
</style>

谷歌爸爸!受我一拜!

業務功能

接下來就是業務部分,計算器嘛還是挺簡單的,感覺最有趣的部分是實時更新計算結果,這個功能通過 vue 這種數據綁定框架來實現真是太合適了。

核心代碼是這樣的,先用 v-for 組裝表單控件:

<div>
<div class="mdl-tabs mdl-js-tabs">
 <div class="mdl-tabs__tab-bar">
 <a v-on:click.prevent="clickTab(0)">滬市 A 股</a>
 <a v-on:click.prevent="clickTab(1)">滬市 B 股</a>
 <a v-on:click.prevent="clickTab(2)">深市 A 股</a>
 <a v-on:click.prevent="clickTab(3)">深市 B 股</a>
 </div>
 <div>
 <div v-for="item of currentTabItem">
 <div>
 <input type="text" id="{{ item.id }}" v-model="item.model"/>
 <label for="{{ item.id }}">{{ item.label }}</label>
 <span>{{ item.suffix }}</span>
 </div>
 </div>
 <div id="result-panel" class="mdl-color-text--primary">
 {{ result }}
 </div>
 </div>
</div>
</div>

然后在 JS 里綁定數據:

export default{
 ready: function (){
 componentHandler.upgradeDom()
 },
 methods: {
 clickTab: function (index){
 this.currentTab = index
 this.$nextTick(() => {
 componentHandler.upgradeDom()
 })
 },
 },
 data: function (){
 return {
 currentTab: 0,
 items: items,
 }
 },
 computed: {
 result: function (){
 ...
 return `${part1}${part2}`
 },
 currentTabItem: function (){
 return items[this.currentTab]
 },
 },
}

這樣一旦輸入的數字發生改變, model 就會改變,就會觸發 result 改變,從而刷新 dom 上的顯示結果。

其他

其他雜七雜八的東西比較多,拎一些踩過的坑記錄一下。

打包

Electron 雖然提供了簡單快捷的跨平臺開發方案,但是并沒有簡單快捷的跨平臺打包方案。從 《 Electron application packaging 》 來看,打包過程比較繁瑣,反正我是劃了5次觸摸板才滾到了底部。

所幸的是, electron-packager 幫我們解決了這個問題,這個工具已經包含在了前面的了 electron-boilerplate-vue 里,現在打包只需以下命令即可:

"package": "node build/package.js",
"package:osx": "node build/package.js --platform=darwin",
"package:mas": "node build/package.js --platform=mas",
"package:win": "node build/package.js --platform=win32",
"package:linux": "node build/package.js --platform=linux",
"release": "npm run build && npm run package",

簽名也很容易,只要加上 osx-sign 的選項即可:

if (packagerConfig.platform === 'mas') {
 Object.assign(packagerConfig, {
 'app-bundle-id': appManifest.bundleId,
 'osx-sign': true,
 })
}

打包之后的結果是 .app 文件,如果需要上傳到 Mac App Store 可以用 electron-osx-flat 將其轉化成 .pkg 文件,然后通過 Xcode 里的 Application Loader 上傳。

然而,并沒那么省心。。。打包之后提交審核,審核人員說你這應用打開白屏了。我自己打開一看還真是。。。感覺是 osx-sign 導致的問題,于是就不打 mas 的包了,還是通過手動寫腳本的方式簽名,參照 Mac App Store Submission Guide 即可。

圖標

圖標問題也卡了幾個小時,主要是因為提交到 iTunes 之后提示說,需要提供 512 和 512@2 的 icns 文件,而打包結果里沒找著。

這就奇怪了,我明明放進去了為什么它找不到呢?后來我仔細看了下我的 icns 文件發現是 png 轉 icns 的時候出了問題。

在我使用 iconvert icons 的時候,導出的圖片沒有 1024*1024 的圖:

而在我使用 cloudconvert 的時候,則只有 1024*1024 的圖:

嗯?!

這不是坑爹嗎!

于是只好手動擼,剛好電腦里有以前做 iOS Icon 時裝的 prepo ,可以將 1024 的 png 導出各個尺寸的圖片并且放到 iconset 里:

然后只要用一行自帶的命令就能將它們打包成 icns 文件:

iconutil -c icns icon.iconset

大功告成。

小結

因為最近忙著搬家的事情,這篇小結就暫時寫到這里。

總的來看, Webpack+Vue+MDL+Electron 開發跨平臺應用是一種很不錯的開發體驗。

雖然一路踩了很多坑,但是在應用上架的那個時刻。

我只想說。

Excited!

 

來自: http://blog.callmewhy.com/2016/07/01/make-calculator-with-electron/

 

 本文由用戶 BonnieReard 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!