iMap | 一款基於 Electron 和 Vue 的跨平臺旅行地圖生成器

項目地址:https://huangxizhou.com/project/iMapjavascript

技術棧

項目目錄

.
├── LICENSE
├── README.md
├── build··········································electron-packager 打包出來的各平臺應用
│   └── icons······································各平臺應用圖標
│       ├── icon.icns
│       ├── icon.ico
│       └── icon.png
├── dist···········································應用構建後的代碼目錄
│   ├── electron
├── package.json···································應用層級的 package.json
├── src············································electron 入口文件文件夾
│   ├── index.ejs
│   ├── main·······································electron 主進程文件文件夾
│   │   ├── index.dev.js
│   │   └── index.js
│   └── renderer···································Vue 相關的目錄
│       ├── App.vue································單頁面的主結構
│       ├── assets·································靜態資源文件夾
│       │   ├── img································項目配圖
│       │   │   ├── china.png
│       │   │   ├── excel_example.png
│       │   │   └── world.png
│       │   └── my-theme···························iVew 自定義主題相關目錄
│       ├── components·····························Vue 相關組件目錄
│       │   ├── Layout·····························佈局組件
│       │   │   └── Header.vue·····················導航欄
│       │   ├── Page·······························頁面組件
│       │   │   ├── Auth.vue·······················用戶權限獲取組件
│       │   │   ├── Chart.vue······················製做地圖組件
│       │   │   ├── ForgetPassword.vue·············忘記密碼組件
│       │   │   ├── Help.vue·······················幫助文檔組件
│       │   │   ├── Home.vue·······················主頁組件
│       │   │   ├── Login.vue······················登陸頁組件
│       │   │   ├── Map.vue························地圖類型組件
│       │   │   ├── MyProject.vue··················個人項目組件
│       │   │   ├── Register.vue···················註冊組件
│       │   │   └── Update.vue·····················登陸組件
│       │   └── Ui·································功能組件
│       │       ├── AddPointModal.vue··············添加地點組件
│       │       ├── DelPointModal.vue··············刪除地點組件
│       │       └── EditPointModal.vue·············修改地點組件
│       ├── data···································Echarts 相關數據存放文件夾
│       │   ├── china.json·························中國地圖 json 數據
│       │   ├── map.js·····························導入座標數據
│       │   └── world.json·························世界地圖 json 數據
│       ├── filter·································Vue 過濾器目錄
│       │   └── index.js
│       ├── main.js································Vue 入口文件
│       ├── router·································Vue 路由文件
│       │   └── index.js
│       ├── server·································ajax相關操做文件
│       │   ├── ajax.js····························二次封裝ajax
│       │   └── url.js·····························接口別名
│       ├── store··································Vuex 數據目錄
│       │   ├── actions.js·························涉及多個 mutations 的 action 集合 
│       │   ├── index.js···························Vuex 入口文件
│       │   ├── modules····························模塊目錄
│       │   │   ├── excel.js·······················Excel 數據相關模塊
│       │   │   └── user_info.js···················用戶數據相關模塊
│       │   └── mutations_types.js·················mutation-types 聲明  
│       ├── tool···································工具文件夾
│       │   └── index.js
│       └── version································應用版本文件夾
│           └── version.js
└── yarn.lock

接口與數據問題

本項目使用的是官方推薦的axioshtml

Axios 是一個基於 promise 的 HTTP 庫,能夠用在瀏覽器和 node.js 中。前端

原本以前想使用 prototype 來寫侵入式代碼,但維護起來仍是很麻煩,最終仍是擼了個開箱即用的 axios 二次封裝的js文件出來:vue

// POST 請求
post({...obj}) {
  return new Promise((resolve, reject) => {
    axios.post(obj.url, obj.data, {
        headers: {
          "Authorization": user && user.accessToken
        }
      }).then((data) => {
      if(data.data.code === 0) {
        // ...
      } else if (data.data.code === 1)  {
        // ...        
      } else {
        // ...  
      }
    }).catch((data) => {
      reject(data)
    })
  })     
}

通常來講,在接收到後端返回的數據時,可使用resolve(data.data)來直接處理數據,固然也能夠按需引入一些 UI 組件與過濾器,直接在 ajax 封裝文件中就能夠過濾數據並進行全局提示,提高用戶體驗。java

對於 GET 請求,因爲項目有使用到百度地圖開放 API 來獲取城市經緯度,涉及到 jsonp 跨域問題,尷尬的是 axios 官方說明不會支持 jsonp ,因此只能引入 jsonp 這個 npm 包,而且將請求此接口從 GET 請求中單獨提取出來。node

getLocation({...obj}) {
    return new Promise((resolve, reject) => {
      jsonp(obj.url + '?' + qs.stringify(obj.data) , null,  (err, data) => {
        if (err) {
          Message.error('請求錯誤')
        } else {
          if(data.status === 0) {
            resolve(data)
          }
        }
      })
    })
  }

GET 請求 ajax 代碼封裝與 POST 基本一致,只是將 obj.data 換成 { paramas: obj.data } 便可。webpack

關於 Vuex 的使用

Vuex是個能把組件的共享狀態抽取出來,當作一個全局單例模式進行管理。這樣無論你在何處改變狀態,都會通知使用該狀態的組件作出相應修改。ios

在本項目中,須要提取到全局管理的數據有 userInfoexcelData,前者保存在全局中,能夠減小請求用戶信息接口的數量,節約資源,後者因爲 Excel 文件上傳到後端後只作解析,不保存,因此全局管理 excelData 很重要。git

在這裏就單獨說一說添加城市座標的操做好了:
首先是 mutations_types 聲明文件github

// mutations_types.js
export const ADD_EXCEL_DATA = 'ADD_EXCEL_DATA'
...

聲明 statemutations
在 Vuex 中,更改 Vuex 的 store 中的狀態的惟一方法就是 mutations

// modules/excel.js
import * as types from '../mutations_types'

// state
const state = {
  excelData: {}
}

// mutations
const mutations = {
  ...
  // 添加 excelData
  [types.ADD_EXCEL_DATA] (state, data) {
    state.excelData.data.push(data)
  },
  ...
}

// 導出 state, mutations
export default {
  state,
  mutations
}

然而,Mutations 必須是同步函數,因此咱們還須要 actions

// actions.js
import * as types from './mutations_types'

...
// 添加 excelData
export const addExcelData = ({ commit }, data) => {
    commit(types.ADD_EXCEL_DATA, data)
}
...

最後,再在入口文件注入 modules 和 actions便可

...
export default new Vuex.Store({
  actions,
  modules: {
    excel
  }
})

這樣一來,關於 excelData 的 數據管理的任督二脈已經打通,如今就看如何來使用了

在組件中可使用 mapStatemapActions 輔助函數來簡化代碼
mapState函數用在計算屬性中

// AddPointModal.vue
  computed: {
    ...mapState({
      excelData: state => state.excel.excelData,
      countAlias: 'excelData'
    })
  }

mapActions 函數在本項目中用於 methods 中

methods: {
    ...mapActions({
      addExcelData: 'addExcelData'
    })
    ...
}

在函數中調用

this.addExcelData(Arrary)

這樣就成功將一個新的數組元素添加到 excelData 中了。

如何獲取 Excel 數據

本項目採用 Leancloud 來做爲後端支持,使用的是Node.js(express),對於獲取用戶的 Excel 數據並不想保存數據的話,本項目的思路是將 Node 做爲一個文件中轉的存在,上傳用戶 Excel 文件至服務器後,在 /public 目錄下保存Excel文件,再在下次用戶上傳時,清空 /public 目錄。

用戶 Excel 處理的庫本項目選擇的是 node-xlsx

特別注意的是,在前端文件中,上傳用戶 Excel 文件是須要使用 formData 來上傳的

let formData = new FormData()
formData.append('file', this.file)

後端使用 formidable 這個庫來接收 Excel 文件並使用 form.parse 來解析。

關於使用 Echarts

ECharts,一個純 Javascript 的圖表庫,能夠流暢的運行在 PC 和移動設備上,兼容當前絕大部分瀏覽器(IE8/9/10/11,Chrome,Firefox,Safari等),底層依賴輕量級的 Canvas 類庫 ZRender,提供直觀,生動,可交互,可高度個性化定製的數據可視化圖表。

對於在 Vue 項目中使用 Echarts , 本項目採用的是 vue-echarts
chart.vue 文件中,咱們利用一個三元運算符來動態切換地圖類型

this.selectMapType === 'china' ?  ECharts.registerMap('china', chinaMap) : ECharts.registerMap('world', worldMap)

對於地圖數據的導入,本項目的方法是的是導入一個對象,返回地圖 option 數據:

// map.js
...
export default {
    getMapData({...obj}) {
    ...
        return {
           // 地圖配置數據
        }
    }
}

再在前端文件中使用這個函數便可: this.option = map.getMapData(this.excelData)

Vue 中父子組件雙向綁定

在本項目中,我將添加、編輯、刪除地點的彈窗所有提取到公用 Ui 組件文件夾中,然而這就須要利用 v-model 來實現組件 props 雙向綁定

// template
<Modal :value="value" v-model="showModal"></Modal>


// script
export default {
  props: {
      value: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return: {
        showModal: false
    }
  },
  watch:{
    value(val) {
      this.showModal = val
    },
    showModal(val) {
      this.$emit('input', val)
    }
  },
  mounted() {
    if (this.value) {
      this.showModal = true;
    }
  }
}

這樣就能使用value來保存 v-model 的值,從而進行雙向綁定。

在MacOS 上打包 Win32 軟件包

在 electron-vue 文檔中有這麼一句話:

If you are wanting to build for Windows with a custom icon using a non-Windows platform, you must have wine installed.

那麼咱們就來安裝wine。首先確保你的 Mac 已經安裝 homebrew,運行 brew install wine 來安裝wine。

接下來,會出現一個錯誤提示,提示咱們須要安裝 Xquartz,按照錯誤提示給的下載網址下載便可。

再次運行 brew install wine

安裝成功後在項目目錄下運行 npm run build:win32 就能夠打包成Win32 安裝包了

求一份工做~

2019年畢業生求帶走

個人簡歷

相關文章
相關標籤/搜索