[筆記] 從零接觸 Google Map API:在 Vue.js 中實作地圖、地標、訊息視窗

Mike Huang
Oct 11, 2019 · 9 min read

最近在準備 Bootcamp 畢業前的 Final Project,由於專案和訂餐平台有關,想說若使用者能透過地圖快速瀏覽營運中的餐廳,或能在訂單上看到地圖顯示領餐地點,可以增加使用者的體驗。由於之前還沒有碰過 Google Map API,更不用說在 Vue.js 當中使用,想說趁專案開始前,能嘗試自學一下,也看一下實作的可行性與成果。以下將筆記「從零接觸 Google Map API,在 Vue.js 中實作地圖、地標、地標訊息視窗」

使用 Google Map API 費用

建立專案

這次只會用到 Maps 的服務,因此點選「Maps」->「continue」:

點選「Create a new project」建立新專案 -> 填寫專案名稱 -> 「Next」:

經過款項帳戶設定後,最終就會拿到一個專案的 API Key,可以先把這個 API Key 複製下來,等會兒在專案中會使用:

管理專案

點選 Console 進入後台

在專案後台可以在最上方切換不同專案及在此專案中新增其他 API 服務,下方則可以看到目前各能使用的狀態,例如已經載入次數等:

如果忘記專案的 API Key 或想更改其權限與設定時,可以點選左左側「Credentials」就能找到:

在 Vue 專案使用 Maps JavaScript API

基本設定與使用

接著在 views 資料夾中建立一個 Restaurants.vue 的檔案,我們想要將地圖呈現出來,因此在 <template> 中合適的地方,加入 <div id=”map”></div> 等下地圖就會呈現在這:

選擇好呈現的位置後,再來就是設定地圖的大小 — 在 Restaurants.vue 檔案裡的 <style> 中,給予地圖適當的寬度和高度:

最後一步,是在 mounted 階段建立一個地圖與一個地標

😃 Map Options 建立地圖時的設定
1. center: 設定地圖的中心點經緯度位置
2. zoom: 設定地圖縮放比例--0 能看到個地球的比例、20 能看到大樓的比例
3. streetViewControl: 設定是否呈現右下角街景小人,讓使用者能使用街景功能
4. mapTypeControl: 設定是否讓使用者可以切換地圖樣式:公路圖、衛星圖等
5. mapTypeControlOptions: 針對「切換地圖樣式」能有更多客製化設定,如樣式等
6. fullscreenControl: 設定是否讓使用者可以點擊開啟全螢幕地圖功能
7. zoomControl: 設定顯示縮放大小的控制鈕(地圖尺寸小於200x200px時預設消失)
8. ZoomControlOptions: 針對縮放大小按鈕有更多設定,如更改在地圖上的擺放位置
Map Option 相關設定在地圖上的示意圖

Voila! 一張簡單的地圖配上一個小地標就能呈現出來了:

顯示一個地圖與一個地標
😃 Marker 地標特效與客製化
1. animation 屬性: 設定地標特效--DROP 為從地圖上方墜落 / BOUNCE 會持續彈跳
2. icon 屬性: 設定使用客製化的地標圖示
3. draggable 屬性: 設定地標可以被使用者拖拉至他處

顯示地標資訊

由於有在地標上綁定點擊事件的監聽器,因此現在只要點擊地標,就會觸發info window的 open() 方法,開啟餐廳資訊視窗:

置放多個地標

建立 Dummy Data

建立一個 xinyi.json 的檔案,以 JSON 格式存放信義區預設的地圖中心點與四間信義區的餐廳名稱、ID、座標位置:

使用 Dummy Data 在地圖上建立四個地標

  1. 首先在 Restaurants.vue 中載入剛建立好的 xinyi.json 檔案,並在 mounted() 階段透過 fetchRestaurants() 取得並更新餐廳與中心點座標
  2. setMarker() 中透過迴圈,在地圖上為四間餐廳分別建立地標與訊息視窗,且在地標加上事件監聽器,在監聽到點擊事件時,開啟訊息視窗:

接著就能在地圖上看到多個地標和效果:

一次只顯示一個地標資訊視窗

訊息視窗透過 open() 方法開啟後,將持續保持開啟狀態,直到使用者點擊關閉的圖示。若希望一次只能開啟一個訊息視窗 — 也就是當點擊第二的地標時,會先將第一個地標的訊息視窗將關閉,才開啟第二個視窗 — 則可以透過 Info Windows 的 close() 方法,指定關閉視窗:

切換地區功能

依照選擇的地區更新地圖資訊

  • 透過 beforeRouteUpdate() ,根據路由的 query string 辨別使用者所點擊的地區,取得相對應的假資料 — 包含該地區的預設中心點及四間營運中的餐廳資料
  • 建立 resetCenter() 方法,設定地圖新的中心點:透過 google.maps.MappanTo() 方法重新給予地圖中心(相對於 setCenter() 方法,panTo() 讓地圖在移動時會有滑順的*移動效果)
  • setMarker() 方法中,先呼叫 deleteMarkers() 方法,將舊的地標刪除後,才建立新地標
  • deleteMarkers() 方法:使用 markersetMap() 方法,並帶入參數 null 移除地標,同時需要清空存有地標的 markers 陣列
❗️ PanTo 滑順移動效果限制
透過 PanTo 更新地圖中心點時,只有當移動距離小於地圖的長度與寬度時,才會有該效果

完成後,點擊不同地區就會顯示該地區營運中的餐廳:

獨立成可重複使用的 Component

預期結果

  1. 獨立地圖產生功能為一個 Component:GMap.vue
  2. 未來在需要的頁面將 Component 引入並帶入相關設定即可使用

建立 GMap.vue Component

在 components 資料夾中建立一個名為 GMap.vue 的檔案,將相關的地圖設定從 Restaurants.vue 抽出放到這個檔案中,並稍做修改與編輯:

在 Restaurants.vue 中使用

接著,只需要在 Restaurants.vue 中載入 GMap.vue 元件,將相關的地圖設定資訊與需要呈現的餐廳資料帶入即可 — 未來其他頁面如果需要使用到地圖時,也可以用相同的方法:

結語

麥克的半路出家筆記

持續培養實力與技能以成為一位更好的軟體工程師 — 紀錄學習心得與心路歷程

麥克的半路出家筆記

持續培養實力與技能以成為一位更好的軟體工程師 — 紀錄學習心得與心路歷程

Mike Huang

Written by

現任全端工程師,熱愛接觸和學習前後端技術與知識、喜歡分享、旅遊和咖啡

麥克的半路出家筆記

持續培養實力與技能以成為一位更好的軟體工程師 — 紀錄學習心得與心路歷程